1

私は、関数がファーストクラスのオブジェクトである新しいクラスベースの動的型付きプログラミング言語に取り組んでいます。 クラス内で定義された関数(別名メソッド)は、自己を第1パラメータとして渡すと呼ばれ、グローバルに定義された関数は自己パラメータを持つ必要はありません。以下のようなコードでコンパイラは自己を渡す必要があるかどうかをどのように決定できますか?

:P1(1234)の最初の引数として、あるいはない渡す必要がある自己場合

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); 
} 

はどのようにコンパイラが決めることができますか?この場合、p1は、の自己パラメータを必要としないグローバル関数であるfooを指しています。

答えて

0

Pythonでは、これは実行時にディスクリプタプロトコルによって処理されます。

Javaは、()でオブジェクトを呼び出さないようにすることでこれを処理します。すべてがメソッド構文で呼び出され、コンパイラはそれが静的メソッドか仮想メソッドかを認識します。 Javaの関数オブジェクトでは、オブジェクト上の特定のメソッドを呼び出す必要があります(foo()の代わりにfoo.call())。

私はC++がこれを型システムを通して処理すると信じています。名前がメソッドの場合は、メソッド呼び出しです。静的メソッドの場合は、静的メソッド呼び出しです。それ以外の場合は、フィールドの()演算子にアクセスしています。

+0

Javaでの呼び出しのタイプを決定するメソッド構文だけではありません。 'abc(1234)'のような式がある場合、 'c(1234)'は 'ab'型で宣言された' static'メソッドや 'bフィールドで見つかったオブジェクト上で呼び出されるインスタンスメソッド'は' a'型の 'static'フィールドか、変数' a'で見つかったオブジェクトのインスタンスフィールドです。重要な点は、コンパイル時に変数、型およびメソッドをルックアップして決定することを可能にする静的型システムです。 – Holger

+0

@Holger「コンパイラが静的メソッドか仮想メソッドかを知っている」と言って、私はそれを試みましたが、私は十分明確ではなかったと思います。また、https://gist.github.com/Storyyeller/fd97cccc02287dd40e43 – Antimony

0

シンプル:c3.p1はメンバー変数であり、c3のメソッドではありません。したがって、c3.p1と呼ぶと、c3のインスタンスを指しているのはselfではありません。あなたはしかし、バインドされたメソッドをサポートする場合があります

:この場合

class c3 { 
    var p1 = 555; 
    func bar() { print "Hello, world"; } 
    func init() { 
     p1 = self.bar; // NOT self.bar() 
    } 
} 

を、コンパイラはまだc3.p1()c3selfの参照を渡すないだろうけどselfはすでにだったので、それは呼び出しサイトでは必要はありませんself.barp1に割り当てられたときにバインドされました。

関連する問題