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
),而不是具體類型。鑒于接口只定義方法(不是成員),并且既沒有方法Foo
也Bar
沒有任何方法,您的接口將是空接口,interface{}
. 傳入的值沒有任何用處,除非您稍后將其轉換回具體類型以訪問其成員,但這并不是接口的真正用途。

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 以表達式中沒有隱式轉換而聞名,但在某些賦值場景中存在隱式轉換。
- 2 回答
- 0 關注
- 142 瀏覽
添加回答
舉報