型Aをレシーバとした際に、値型を選択することの制限が以下のように書いてある。
あるポインタインスタンスに対しては、ポインタレシーバも値レシーバもそのポインタインスタンスのメソッドセットに含まれます。これに対して、値型インスタンスの場合、値レシーバのメソッドだけがメソッドセットに含まれます。
これはもう少し正確に言うと、値が アドレス指定可能(addressable)かどうか」 によって挙動が変わる
となる。
例えば以下のようにコンパイラがアドレスを判別できれば、自動的に&をつけてくれるのでポインタメソッドを呼ぶことは可能
type A struct{ x int }
func (a A) valueMethod() { fmt.Println("value", a.x) }
func (a *A) pointerMethod() { a.x++; fmt.Println("pointer", a.x) }
func main() {
var ap *A = &A{1}
ap.valueMethod() // OK
ap.pointerMethod() // OK
var av A = A{10}
av.valueMethod() // OK
av.pointerMethod() // OK ← アドレス取得が自動で挿入される
// (実質 (&av).pointerMethod())
}
ただし、以下のようにアドレス指定ができない場合は、呼び出すことが出来ない
A{3}.pointerMethod() // リテラルは addressable でない
getA().pointerMethod() // 戻り値は一時値で addressable でない