一、先來看一段代碼
package mainimport "fmt"type X struct{}func (x *X) test(){println("h1",x)
}
func main(){a := X{} a.test()(&X{}).test()(X{}).test()
}
猜猜他的結果
二、揭曉答案
package mainimport "fmt"type X struct{}func (x *X) test(){println("h1",x)
}
func main(){a := X{} a.test() // 正確(&X{}).test() // 正確 (X{}).test() // 報錯 cannot call pointer method on X literal
}
三、為什么會是這樣的
- 聲明賦值后調用指針方法
a :=x
a.test() //正確
指針方法可以調用的條件:receiver 必須是合法的指針(包括nil) 或者 能夠獲取實例的地址 a 是一個可以尋址的變量 ,所以可以調用test() 指針方法When the value is addressable, the language takes care of the common case of invoking a pointer method on a value by inserting the address operator automatically.翻譯:當值是可被尋址的,go語言會處理通常的情況:在一個值上面調用它的指針方法,編譯器會自動插入一個&取地址操作符
- (&X{}).test() 正確
指針方法可以調用的條件:receiver 必須是合法的指針(包括nil) 或者 能夠獲取實例的地址 (&X{}) 是一個合法的指針
- (X{}).test() 報錯
變量名 = 右值X{} 就是右值右值 是不可尋址的(unaddressable) ,所以會報錯
四、疑問
(X{}).test() 不可尋址 報錯了
為什么
(&X{}).test() 能取到地址了?