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

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

Golang 結構類型轉換

Golang 結構類型轉換

Go
搖曳的薔薇 2022-12-26 10:35:58
我試圖弄清楚 go 如何處理結構之間的類型轉換。我讀過的所有內容都告訴我,具有相同底層類型的類型被認為是兼容的,并且類型轉換是隱式發生的。如果是這樣,為什么下面的代碼不起作用?Foo和都Bar實現了FooI接口,并且都添加了一個x字符串類型的屬性。然而,當我將一個類型結構傳遞給需要類型Bar結構AcceptBarOrFoo的結構時Foo,我得到了一個類型不匹配的編譯錯誤。去游樂場package mainimport (    "play.ground/bar"    "play.ground/foo")func main() {    AcceptBarOrFoo(bar.Bar{})}func AcceptBarOrFoo(foo.Foo) interface{} {    return nil}// -- iface/iface.go --package ifacetype FooI interface {    a() string    b(int) int}// -- foo/foo.go --package fooimport (    "play.ground/iface")type Foo struct {    iface.FooI    x string}// -- bar/bar.go --package barimport (    "play.ground/iface")type Bar struct {    iface.FooI    x string}
查看完整描述

2 回答

?
狐的傳說

TA貢獻1804條經驗 獲得超3個贊

您永遠無法將一種具體類型轉換為另一種具體類型。它們不一樣。在 Go 中無法定義這種類型的自動轉換。充其量,您可以定義一個函數,該函數接受 aBar并構建并返回一個新Foo的,其字段設置為與輸入相同的值Bar。

我讀過的所有內容都告訴我,如果底層類型相同,則高階類型被認為是兼容的,類型轉換會隱式發生

目前還不清楚你的來源是什么,但沒有任何東西會說明或暗示這一點,這根本不是真的。Go 不進行任何隱式轉換。這是 Go 的一個大聲宣傳的功能。鑒于type Foo struct { a int }and type Bar struct { a int },您永遠不能將類型的對象分配給類型Bar的變量Foo。

當類型滿足接口時,您可以從任一具體類型轉換為接口類型。您的AcceptBarOrFoo方法應該接受接口類型(兩者都Foo滿足Bar),而不是具體類型。鑒于接口只定義方法(不是成員),并且既沒有方法FooBar沒有任何方法,您的接口將是空接口,interface{}. 傳入的值沒有任何用處,除非您稍后將其轉換回具體類型以訪問其成員,但這并不是接口的真正用途。


查看完整回答
反對 回復 2022-12-26
?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

Foox與 Bar 不同,x因為非導出標識符在包邊界之間永遠不相等。通過導出foo.Foo 和 bar.Bar 中的字段來修復:


type Foo struct {

    iface.FooI

    X string // <-- start with capital letter to export

}

要使用 foo.Foo 或 bar.Bar 作為參數值,foo.Foo 和 bar.Bar 必須可分配給參數的類型。使用 foo.Foo 作為參數類型是行不通的,因為命名類型不能相互分配。但是,當兩種類型共享相同的基礎類型時,命名類型可分配給未命名類型。將參數聲明為未命名類型:


func AcceptBarOrFoo(struct {

    iface.FooI

    X string

}) interface{} {

    return nil

}

通過這些更改,可以編譯以下代碼:


AcceptBarOrFoo(bar.Bar{})

AcceptBarOrFoo(foo.Foo{})

在 Go 操場上運行示例


另一種選擇是使用到通用類型的轉換。在下面的代碼中,foo.Foo 是普通類型,bar.Bar 被轉換為 foo.Foo。


func Accept(foo.Foo) interface{} {

    return nil

}


... 


Accept(foo.Foo{})

Accept(foo.Foo(bar.Bar{}))

在 Go playground 上運行示例。


注意:foo.Foo 和 bar.Bar 必須具有相同的字段才能使上述工作正常(導出字段名稱,字段順序相同,字段類型相同)。


關于 Go 的一些注意事項:


存在從一種具體類型到另一種具體類型的轉換。

Go 以表達式中沒有隱式轉換而聞名,但在某些賦值場景中存在隱式轉換。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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