编译器如何决定是否需要传递自我?

时间:2016-06-15 12:58:34

标签: compilation compiler-construction bytecode interpreter first-class-functions

我正在研究一种新的基于动态类型的编程语言,其中函数是第一类对象。 在类(也称为方法)中定义的函数称为传递 self 作为第一个参数,而全局定义的函数不需要具有self参数。

代码如下:

func foo(a) {
    return a*2;
}

class c3 {
    var p1 = 555;
    func init() {
        p1 = foo;
    }
}

class c2 {
    var p1 = 333;
    func init() {
        p1 = c3();
    }
}

class c1 {
    var p1 = 111;
    func init() {
        p1 = c2();
    }
}

func main() {
    return c1().p1.p1.p1(1234);
}

编译器如何判断是否需要将 self 作为第一个参数传递给p1(1234)?在这种情况下,p1指向foo,这是一个不需要 self 参数的全局函数。

2 个答案:

答案 0 :(得分:0)

在Python中,这是由描述符协议在运行时处理的。

Java通过不允许使用()调用对象来处理此问题。使用方法语法调用所有内容,编译器知道它是静态方法还是虚方法。函数对象的Java等价物要求您在对象上调用特定方法(foo.call()而不是foo())

我相信C ++通过类型系统来处理这个问题。如果名称是方法,则它是方法调用。如果它是静态方法,则它是静态方法调用。否则,您正在访问字段上的()运算符。

答案 1 :(得分:0)

简单:c3.p1是成员变量,不是c3的方法。因此,当您致电WalkerSpeaker时,它根本没有c3.p1指向self的任何实例。

您可能希望支持绑定方法:

c3

在这种情况下,编译器仍然不会将class c3 { var p1 = 555; func bar() { print "Hello, world"; } func init() { p1 = self.bar; // NOT self.bar() } } c3引用传递给self,但自{{1}以来在调用网站上没有必要当c3.p1()被分配到self时,}}已被绑定。