在 Go 中传入值或将地址传递到接口之间有什么区别?

假设我们有一个简单的接口和实现:


type Vertex struct {

    X int

    Y int

}


type Abser interface {

    Abs() float64

}


func (v Vertex) Abs() float64 {

    sum := float64(v.X + v.Y)

    return math.Sqrt(sum)

}

现在我有一个接口变量:


var abser Abser

我想为它设置一个顶点。我可以设置一的值,或者一个的地址:


v := Vertex{1, 1}

abser = v

abser = &v

两者之间有什么区别?为什么设置顶点的地址有效?这与界面在引擎盖下的工作方式有何关系?我对Go还很陌生,所以任何帮助将不胜感激 🙏


qq_遁去的一_1
浏览 76回答 2
2回答

翻阅古今

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

慕哥6287543

首先,在Go中,一切都是按价值传递的。指针按值传递 - 使用指针的副本。切片按值传递 - 复制指向基础数组的指针、长度的整数值和容量的整数值。接口也按值传递 - 使用接口值的副本。如果你这样想,它会有所帮助。现在,让我们关注接口:接口值由两部分组成:指向接口表的指针指向实际值的指针因此,当您传递接口时,您实际上是在复制两个指针。现在,要使类型满足接口,它需要具有接口所需的方法。如果任何方法使用指针接收器(如您的示例中所示),那么您将需要一个指向该值的指针来满足接口,这就是为什么您需要获取它的地址。func (v *Vertex) Abs() float64 {...}假设没有一个方法需要指针接收器(比如说)。然后,您不需要指定地址,因为您只需传递它而不获取其地址。func (v Vertex) Abs() float64 {...}我希望这能回答你的问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go