type Itest interface {
SayHello()
}
var G_Test Itest
type TestS struct {
id_ int
}
func (ts TestS)SayHello() {
ts.id_ = 1
}
type TestP struct {
id_ int
}
func (tp *TestP)SayHello() {
tp.id_ = 1
}
func main() {
G_Test = TestS{} //OK
G_Test = &TestS{} //OK
G_Test = TestP{} //compile error:cannot use TestP literal (type TestP) as type Itest in assignment:
//TestP does not implement Itest (SayHello method has pointer receiver)
G_Test = &TestP{} //OK
}
代码如上,TestS 和 TestP 都实现了接口 Itest,TestS 方法接收者是本身, TestP 方法接收者是其指针,然后为什么会报这种错误?
为什么当接收者不是指针的时候可以结构体本身和指针都能赋值给接口,而接收者是指针的时候就不行?
是否和隐式转换有关?
观察很多源码包(如bytes.Buffer,bytes.NewBuffer()返回的指针)都是写成接收者是指针,然后New结构体的方法返回的是指针。这样写的好处是什么?还是说是约定俗成?
- go语言圣经中有句话:`在T类型的参数上调用一个*T的方法是合法的,只要这个参数是一个变量;编译器隐式的获取了它的地址。但这仅仅是一个语法糖:T类型的值不拥有所有*T指针的方法,那这样它就可能只实现更少的接口。`
#2
更多评论
以值为接收者的方法被调用时,接收者既能为值又能为指针。
我之前记的这句话,但是不记得在哪本书里了 - -
所以func (ts TestS)SayHello() 在调用时候&TestS{}可以自动解析为*(&TestS{}) 也就满足了接口的定义
但是如果方法的接收者是指针的话,应该就不能自动解析了吧。所以接口赋值报错。
所以应该是为了写的时候方便,这是我自己的理解,希望能够帮到你
#1