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

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

關于接口分配

關于接口分配

Go
胡子哥哥 2023-07-26 16:42:08
當將結構體指針分配給接口時,為什么 Go 不認為這是類型不匹配錯誤?package mainimport "fmt"type ABC interface {    a() string    b() int}type XYZ struct {    aa string    bb int}func (xyz XYZ) a() string {    return "XYZ"}func (xyz XYZ) b() int {    return 123}func main() {    var xyz *XYZ    var abc ABC = xyz // type of abc is *main.XYZ,I think that Golang can find this error here, but why not?    fmt.Printf("%T\n", abc)    a, ret := abc.(*XYZ)    fmt.Println(a, ret) // type of a is *main.XYZ    fmt.Println(a.a()) // will occur a error, because the type of a(*main.XYZ) not implements the interface ABC}我想知道為什么 Go 不認為這是“var abc ABC = xyz”處的錯誤
查看完整描述

3 回答

?
桃花長相依

TA貢獻1860條經驗 獲得超8個贊

XYZ 確實實現了 ABC。這與如何確定方法集有關(添加重點):

類型可以具有與其關聯的方法集。接口類型的方法集就是它的接口。任何其他類型 T 的方法集由接收者類型 T 聲明的所有方法組成。對應指針類型 *T 的方法集是接收者 *T 或 T 聲明的所有方法的集合(即還包含接收者類型 T 聲明的方法)。集 T)。

方法集決定接口是否實現:

接口類型指定稱為其接口的方法集。接口類型的變量可以存儲任何類型的值,其方法集是接口的任何超集。這樣的類型被稱為實現接口。

當調用 時*XYZ.a(),Go 編譯器總是可以自動解引用指針來獲取值接收者。這樣做沒有任何缺點,因為接收者無法修改(就調用者而言)。

當且僅當該值是可尋址時,反邏輯才成立:

type T struct {}

func (*T) M()


func main() {

? ? var t T

? ? t.M() // ok; t is addressable and the compiler rewrites this to (*t).M()


? ? var m map[string]T

? ? m["x"].M() // error: cannot take the address of m["x"]

}


查看完整回答
反對 回復 2023-07-26
?
ABOUTYOU

TA貢獻1812條經驗 獲得超5個贊

會出現錯誤,因為a(*main.XYZ)的類型沒有實現接口ABC

錯誤的。*main.XYZ實現ABC(否則abc = xyz會在編譯時失敗,嘗試將方法重命名bc例如),但該變量a保存一個nil指針(類型為*XYZ)。由于該方法具有值接收器,因此要調用該方法,必須取消XYZ.a()引用類型的指針值。*XYZ但是nil指針不指向任何內容,它不能被取消引用,嘗試這樣做會導致運行時恐慌,就像您所經歷的那樣。

如果您xyz從一開始就使用非nil指針進行初始化,那么它會起作用:

var xyz *XYZ = new(XYZ)

在Go Playground上嘗試一下。

另請注意,如果XYZ.a()XYZ.b()會有指針接收器,那么如果xyznil

func (xyz *XYZ) a() string {

    return "XYZ"

}


func (xyz *XYZ) b() int {

    return 123

}


func main() {

    var xyz *XYZ

    // ...

在Go Playground上嘗試一下。這樣做的原因是因為如果接收者是指針,則nil不必取消引用指針即可調用帶有指針接收者的方法,因此不會發生運行時恐慌。當然,如果在方法中您引用XZY.aaXYZ.bb字段,那將是運行時恐慌,但您當前的方法實現不會這樣做,所以它可以工作。



查看完整回答
反對 回復 2023-07-26
?
四季花海

TA貢獻1811條經驗 獲得超5個贊

當我在值上調用方法時(不是指針,是實現接口的結構的方法,并且方法的接收者是指針)。Golang會創建一個新對象,并從原始struct值中復制值,然后,iface.data將指向新對象,現在,當我們將新對象的指針傳遞給方法時,它可以被修改,但是這個操作不會改變原始結構體值,這沒有任何用處,因此,當我們將結構體值分配給接口(指針接收者)時,Golang會發生錯誤



查看完整回答
反對 回復 2023-07-26
  • 3 回答
  • 0 關注
  • 208 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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