正如GO规范中的那样,类型T的方法集由所有接收者类型为T的方法组成,而对应的指针类型T的方法集由所有接收者为*T或T的方法组成,也就是说T的方法集包括T的方法集,但这并不冲突。( That means the method set of *T includes that of T, but not the reverse.)
这种区别产生的原因是,如果一个接口值包含一个指针*T,方法调用可以通过去引用该指针来获得一个值,但是如果一个接口值包含一个值T,方法调用就没有安全的方法来获得一个指针。(这样做会让方法修改接口内部的值的内容,这是规范所不允许的)。
即使在编译器可以取值的地址传递给方法的情况下,如果方法修改了值,那么修改的内容也会在调用者中丢失。举个例子,如果bytes.Buffer的Write方法使用了一个值接收器而不是指针,这段代码。
如Go规范所述,类型T的方法集由接收者类型T的所有方法组成,而对应的指针类型* T的方法集由接收者* T或T的所有方法组成。这意味着* T的方法集 包括T的值,但不包括T的值。
之所以会出现这种区别,是因为如果接口值包含指针* T,则方法调用可以通过取消引用指针来获取值,但是如果接口值包含值T,则方法调用就没有安全的方法来获取指针。 (这样做将允许一种方法修改接口内部值的内容,这是语言规范所不允许的。)
即使在编译器可以将值的地址传递给方法的情况下,如果方法修改了该值,则更改也将在调用方中丢失。 例如,如果bytes.Buffer的Write方法使用值接收器而不是指针,则此代码:
var buf bytes.Buffer
io.Copy(buf, os.Stdin)
会将标准输入复制到 buf 的副本中,而不是复制到 buf 本身。这不是我们想要的。
Golang 外文翻译golang.org/doc/faq#dif…