ホームページ >バックエンド開発 >Golang >ポインター レシーバー メソッドを呼び出すときに Go が暗黙的に逆参照するのはなぜですか?

ポインター レシーバー メソッドを呼び出すときに Go が暗黙的に逆参照するのはなぜですか?

DDD
DDDオリジナル
2024-12-02 07:03:10864ブラウズ

Why Does Go Implicitly Dereference When Calling Pointer Receiver Methods?

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。