3 回答

TA貢獻1810條經驗 獲得超4個贊
這些類型的問題通常是以下結果:
過早的接口
假界面,或“氣泡包裝”(請參閱我的咆哮 這里)
并行接口
您遇到的錯誤與第 3 個問題最具體相關,但每個錯誤都存在于此處的示例設計中。
好的接口應該傳達(以它們的名稱和方法簽名)一組行為。接口的名稱應由它包含的方法暗示,因為該名稱只是應該捕獲該行為的本質。
為此目的似乎唯一需要的接口是:
type Mover interface {
Move() MoveResult
}
對于 MoveResult,您可以執行此操作(如果您愿意,可以使用 int 交換 float):
type MoveResult struct {
Distance, Height float64
}
給定以下假設,此類型可以作為結構很好地發揮作用:
移動結果只是數據點(它們不需要是動態的;您可以設置值并保留它們)
“額外”數據(如高度)在未指定時以零值正確運行。
現在,實現 bird 類型:
type Bird struct {
// some internal data
}
func (b *Bird) Move() MoveResult {
// some movement calculations
return MoveResult{Distance: howFar, Height: howHigh}
}
現在實現 foo:
func foo(m Mover) float64 {
return m.Move().Distance
}
現在主要使用它:
func main() {
foo(&Bird{})
}
現在我們可以將其他類型的s添加到程序中,并毫無問題地使用它們。Moverfoo
解決您的注釋,其中 和 都是外部的,您無法修改它們:AnimalAnimalMoveResultfoo
我如何用我的理解提出問題:有這個函數,旨在接受一個名為的接口,其特征是它如何返回專有類型。您希望將類型用作 ,但無法將所需的所有行為都適合該專有返回類型。fooAnimalBirdAnimal
那么如何解決這個問題呢?
實現您自己的、更廣泛的返回類型
type birdMoveResult struct {
// some internal data
}
func (r birdMoveResult) GetDistance() int {
// get the distance
}
func (r birdMoveResult) GetHeight() int {
// get the height
}
現在,實現 Bird 類型
type Bird struct {
// some internal data
}
func (b *Bird) Move() AnimalMoveResult {
var result birdMoveResult
// calculate the move result
return birdMoveResult
}
請注意,返回類型,因此現在將滿足接口。我們能夠做到這一點,因為滿足類型,所以在這里返回它是合法的。MoveAnimalMoveResultBirdAnimalbirdMoveResultAnimalMoveresult
剩下的問題是 s 方法縮小了寬界面的范圍,我們實際上已經丟失了您添加的新功能。為了在仍然滿足接口的同時將其取回,我們根本無法更改方法簽名。以下是 2 種可能的解決方法。BirdMoveAnimalMove
使用 bird 類型時,您可以對結果進行類型斷言,以訪問額外的方法
var b Bird
// ...
height := b.Move().(birdMoveResult).GetHeight()
向中添加一個新方法,該方法返回更廣泛的類型,使現有方法具有相同的簽名BirdMove
func (b *Bird) MoveFull() birdMoveResult {
var result birdMoveResult
// calculate the move result
return birdMoveResult
}
func (b *Bird) Move() AnimalMoveResult {
return b.MoveFull()
}
height := b.MoveFull().GetHeight()
這些都可以工作,這主要是偏好問題。

TA貢獻1817條經驗 獲得超14個贊
在Go中,有沒有辦法使用方法實現接口,其中實現中相應方法的返回類型是“比”預期的返回類型“寬”的?
不。方法簽名必須按字面匹配。圍棋沒有協變或逆變的概念。

TA貢獻2012條經驗 獲得超12個贊
Go的類型系統使用類型名稱匹配。即使使用不同的類型名稱返回相同的接口,此操作也會失敗。
但是,您可以聲明該方法以滿足接口,但返回可以類型斷言的更廣泛的實現。
- 3 回答
- 0 關注
- 98 瀏覽
添加回答
舉報