2 回答

TA贡献1780条经验 获得超5个赞
在 Go 类型系统中,使用类型的值接收器定义的方法为 和 定义,即:TT*T
func (v Vertex) Abs() float64 {...}
这适用于 和 。该方法本身始终接收 的副本。v*vv
为 定义的方法仅为 定义,而不为 定义。那是:*T*TT
func (v *Vertex) SetX(newx float64) {v.X=newx}
该方法仅在接收方可寻址时才有效。这是必要的,这样您就不会编写丢失数据的代码。例如:SetX
m:=map[string]Vertex{}
m["a"]=Vertex{}
m["a"].SetX(1) // This fails! m["a"] is not addressable
如果上述情况没有失败,则 将设置 的副本,并且效果将丢失,因为更新后的副本不会放回地图中。SetXm["a"]
回到接口:您的接口由任何实现 的类型实现。基于上面的讨论,既要实现.AbserAbs() float64Vertex*VertexAbser
假设您定义为:Vertex.Abs
func (v *Vertex) Abs() float64 {...}
然后,仅实现 ,因此:*VertexAbser
abser = v // This would fail
abser = &v // This would work

TA贡献1831条经验 获得超10个赞
首先,在Go中,一切都是按价值传递的。
指针按值传递 - 使用指针的副本。
切片按值传递 - 复制指向基础数组的指针、长度的整数值和容量的整数值。
接口也按值传递 - 使用接口值的副本。
如果你这样想,它会有所帮助。
现在,让我们关注接口:
接口值由两部分组成:
指向接口表的指针
指向实际值的指针
因此,当您传递接口时,您实际上是在复制两个指针。
现在,要使类型满足接口,它需要具有接口所需的方法。如果任何方法使用指针接收器(如您的示例中所示),那么您将需要一个指向该值的指针来满足接口,这就是为什么您需要获取它的地址。func (v *Vertex) Abs() float64 {...}
假设没有一个方法需要指针接收器(比如说)。然后,您不需要指定地址,因为您只需传递它而不获取其地址。func (v Vertex) Abs() float64 {...}
我希望这能回答你的问题。
- 2 回答
- 0 关注
- 75 浏览
添加回答
举报