Go メソッド セット: ポインター型とレシーバーのメソッドの呼び出し
Go メソッド セットのよく議論される側面の 1 つは、呼び出しを試みたときに発生します。型 T の変数に対するレシーバー型 T のメソッド。Go 仕様では、 T には、レシーバー タイプ *T のメソッドとレシーバー タイプ T のメソッドの両方が含まれます。
競合する推論
ただし、次の例は、この推論が可能であることを示しています。直観に反するようです:
package main import ( "fmt" "reflect" ) type User struct{} func (self *User) SayWat() { fmt.Println(self) fmt.Println(reflect.TypeOf(self)) fmt.Println("WAT\n") } func main() { var user User = User{} fmt.Println(reflect.TypeOf(user), "\n") user.SayWat() }
コンパイラー推論
コンパイラーは、変数 user の型が T であるにもかかわらず、 user.SayWat() がレシーバー型 *T でメソッドを呼び出すと推論します。 この動作は、コンパイラーによる & の自動挿入によって引き起こされます。演算子のアドレス。本質的には、(&user).SayWat() への呼び出しを書き換えます。
ポインター型のメソッドの呼び出し
ポインター型のメソッドは型 T の変数に対して呼び出されますが、これは厳密には当てはまりません。コンパイラーは *T 型のレシーバーを使用し、T への &user の逆参照は暗黙的な操作です。
暗黙的な逆参照の例外
ただし、これは暗黙的です。逆参照はすべての場合に適用されるわけではありません。戻り値 (アドレス指定不可) のポインター レシーバーを使用してメソッドを呼び出すと、次のようなコンパイル時エラーが発生します。
func aUser() User { return User{} } ... aUser().SayWat()
エラー メッセージ
cannot call pointer method on aUser() cannot take the address of aUser()
以上がポインター レシーバー メソッドを呼び出すときに Go が暗黙的に逆参照するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。