2 回答

TA貢獻1874條經驗 獲得超12個贊
解釋可能令人驚訝,但實際上很簡單。
foo_gen
被定義為func () (Foo, error)
,所以第一個返回值的類型Foo
是 ,它是一個接口。
任何接口類型的值都是struct
具有兩個指針的:指向該接口值中實際保存的具體值和指向(一些內部對象表示)它的類型。關于如何實現接口值的經典且非常好的(如果可能有點生疏)解釋是this。
您嘗試匹配我們剛剛討論的簽名的實際函數返回一個類型的值Bar
作為它的第一個返回值。該類型是一種struct
類型,它與原始簽名所期望的接口值無關。
換句話說,為了讓你的函數返回一個類型的值Bar
滿足期望接口類型值的簽名,Foo
編譯器必須生成代碼,將返回的值復制Bar
到堆并從中合成一個值Foo
。雖然可能是可行的,但這太含蓄了,否則可能會令人驚訝。
由于幾乎相同的原因,編譯器不允許將切片分配給[]T
類型變量。[]interface{}

TA貢獻1776條經驗 獲得超12個贊
在類型級別上,這就是正在發生的事情。
問題是 go 編譯器無法將 a 提升func () (bar, error))到 afunc () (Foo, error)因為通常 go 值不是covariant。
這樣做的結果是有幾種方法可以解決這個問題。
一種是改變函數的返回類型:
foo_gen := func () (Foo, error) {
return bar{}, nil
}
這是有效的,因為它能夠輕松地將bar{}值提升到一個Foo值。
如果我無法更改生成器函數(這也適用于通道等),另一種方法是將生成器包裝在另一個函數中:
bar_gen := func () (bar, error){
return bar{}, nil
}
foo_gen := func() (Foo, error){
foobar, err := bar_gen()
return foobar, err
}
- 2 回答
- 0 關注
- 105 瀏覽
添加回答
舉報