亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Go 中傳入值或將地址傳遞到接口之間有什么區別?

在 Go 中傳入值或將地址傳遞到接口之間有什么區別?

Go
qq_遁去的一_1 2022-10-04 19:27:45
假設我們有一個簡單的接口和實現: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 = vabser = &v兩者之間有什么區別?為什么設置頂點的地址有效?這與界面在引擎蓋下的工作方式有何關系?我對Go還很陌生,所以任何幫助將不勝感激 ??
查看完整描述

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


查看完整回答
反對 回復 2022-10-04
?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

首先,在Go中,一切都是按價值傳遞的。

指針按值傳遞 - 使用指針的副本。

切片按值傳遞 - 復制指向基礎數組的指針、長度的整數值和容量的整數值。

接口也按值傳遞 - 使用接口值的副本。

如果你這樣想,它會有所幫助。

現在,讓我們關注接口:

接口值由兩部分組成

  1. 指向接口表的指針

  2. 指向實際值的指針

因此,當您傳遞接口時,您實際上是在復制兩個指針。

現在,要使類型滿足接口,它需要具有接口所需的方法。如果任何方法使用指針接收器(如您的示例中所示),那么您將需要一個指向該值的指針來滿足接口,這就是為什么您需要獲取它的地址。func (v *Vertex) Abs() float64 {...}

假設沒有一個方法需要指針接收器(比如說)。然后,您不需要指定地址,因為您只需傳遞它而不獲取其地址。func (v Vertex) Abs() float64 {...}

我希望這能回答你的問題。


查看完整回答
反對 回復 2022-10-04
  • 2 回答
  • 0 關注
  • 87 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號