为了账号安全,请及时绑定邮箱和手机立即绑定

方法集(指针与值接收器)

方法集(指针与值接收器)

Go
智慧大石 2021-11-22 15:06:47
我很难理解为什么这些规则与指针类型 .vs 的方法集相关联。值类型有人可以解释原因吗(从接口表的角度)(摘自威廉肯尼迪的博客)Values          Methods Receivers-----------------------------------------------T               (t T)*T              (t T) and (t *T)Methods Receivers    Values-----------------------------------------------(t T)                 T and *T(t *T)                *T规范的片段方法集一个类型可能有一个与之关联的方法集。接口类型的方法集就是它的接口。任何其他类型 T 的方法集由所有以接收者类型 T 声明的方法组成。 对应指针类型 *T 的方法集是所有以接收者 *T 或 T 声明的方法的集合(即,它还包含方法组 T)。更多规则适用于包含匿名字段的结构,如结构类型部分所述。任何其他类型都有一个空的方法集。在一个方法集中,每个方法必须有一个唯一的非空方法名。类型的方法集决定了该类型实现的接口以及可以使用该类型的接收器调用的方法。
查看完整描述

2 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

来自Golang 常见问题解答

正如 Go 规范所说,类型 T 的方法集由接收器类型为 T 的所有方法组成,而对应指针类型 *T 的方法集由接收器类型为 *T 或 T 的所有方法组成。 这意味着 *T 的方法集包括 T 的,但不包括相反的。

出现这种区别是因为如果接口值包含指针 *T,则方法调用可以通过取消引用指针来获取值,但是如果接口值包含值 T,则方法调用没有安全的方法获取指针。(这样做将允许方法修改接口内的值的内容,这是语言规范所不允许的。)

即使在编译器可以将值的地址传递给方法的情况下,如果方法修改了值,则更改将在调用者中丢失。例如,如果 bytes.Buffer 的 Write 方法使用值接收器而不是指针,则此代码:

var buf bytes.Buffer
io.Copy(buf, os.Stdin)

会将标准输入复制到 buf 的副本中,而不是复制到 buf 本身中。这几乎从来都不是理想的行为。


查看完整回答
反对 回复 2021-11-22
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

  1. 如果您有一个,*T您可以调用接收器类型*T为 的方法以及接收器类型为T(您引用的段落, 方法集)的方法

  2. 如果您有 aT并且它是可寻址的,您可以调用接收器类型*T为 的方法以及接收器类型为T的方法,因为方法调用t.Meth()将等效于(&t).Meth()Calls )。

  3. 如果您有 aT并且它不可寻址(例如,函数调用的结果,或索引到映射的结果),Go 无法获得指向它的指针,因此您只能调用具有 a 的方法的接收器类型T,不是*T

  4. 如果您有一个接口I,并且I的方法集中的部分或全部方法由接收器为 的方法提供*T(其余方法由接收器为 的方法提供T),则*T满足接口I,但T不满足。那是因为*T的方法集包括T's,但不是相反的(再次回到第一点)。

简而言之,您可以混合和匹配带有值接收器的方法和带有指针接收器的方法,并将它们与包含值和指针的变量一起使用,而不必担心哪个是哪个。两者都可以使用,并且语法相同。然而,如果需要带有指针接收器的方法来满足接口,那么只有一个指针可以分配给接口——一个值将是无效的。


查看完整回答
反对 回复 2021-11-22
  • 2 回答
  • 0 关注
  • 136 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信