0xf

日記だよ

goの&と*がいつも混乱する

かんぜんに書き慣れてないからですね。今日はメソッド定義時のレシーバについてちょっと悩んでた。

type User struct {
    name string
}

func (u User) getName() string {
    return u.name
}

func Test() {
    fmt.Println(User{name: "Pop"}.getName())
}

これは u User が普通の参照型で、 呼び出し時のレシーバもUser{name: "Pop"}も普通の参照型なのでOK。

type User struct {
    name string
}

func (u *User) getName() string {
    return u.name
}

func Test() {
    fmt.Println((&User{name: "Pop"}).getName())
}

これは u *User が Userのポインタを要求している。呼び出しレシーバになってる (&User{name: "Pop"})は、まずUser{name: "Pop"}が作られた後そのオブジェクトをデリファレンスしてポインタを取り出しているので、ポインタがレシーバとなりメソッドがよべる。OK。

&User{name: "Pop"}.getName() だと cannot call pointer method getName on User と言われてコンパイルできないのはたぶんデリファレンス演算子である & がメソッド呼び出しの . より優先度が低いからだろうか。単項演算子の優先度って最大なのでは? と思っていたけど違うんだろうか。

あとでThe Go Programming Language Specification - The Go Programming Language 眺める。