go method的receiver是一个指针与结构的一点区别

type Box struct {
  color Color
}

func (b *Box) SetColor(c Color) {
    b.color = c
}

func (b Box) SetColor(c Color){
    b.color = c
}
现在让我们回过头来看看SetColor这个method,它的receiver是一个指向Box的指针,是的,你可以使用*Box。想想为啥要使用指针而不是Box本身呢?

我们定义SetColor的真正目的是想改变这个Box的颜色,如果不传Box的指针,那么SetColor接受的其实是Box的一个copy,也就是说method内对于颜色值的修改,其实只作用于Box的copy,而不是真正的Box。所以我们需要传入指针。

这里可以把receiver当作method的第一个参数来看,然后结合前面函数讲解的传值和传引用就不难理解

这里你也许会问了那SetColor函数里面应该这样定义*b.Color=c,而不是b.Color=c,因为我们需要读取到指针相应的值。

你是对的,其实Go里面这两种方式都是正确的,当你用指针去访问相应的字段时(虽然指针没有任何的字段),Go知道你要通过指针去获取这个值,看到了吧,Go的设计是不是越来越吸引你了。

也许细心的读者会问这样的问题,PaintItBlack里面调用SetColor的时候是不是应该写成(&bl[i]).SetColor(BLACK),因为SetColor的receiver是*Box,而不是Box。

你又说对的,这两种方式都可以,因为Go知道receiver是指针,他自动帮你转了。

也就是说:

如果一个method的receiver是*T,你可以在一个T类型的实例变量V上面调用这个method,而不需要&V去调用这个method
类似的

如果一个method的receiver是T,你可以在一个*T类型的变量P上面调用这个method,而不需要 *P去调用这个method
http://www.kancloud.cn/kancloud/web-application-with-golang/44154

猜你喜欢

转载自hhg08.iteye.com/blog/2282181