您嘗試使用面向對象的設計模式與繼承。這並不是Go如何做到這一點。除此之外,接口名稱以Java的'able'或等同的面向對象的語言結束。在Go中,慣例是用'er'結束接口名稱。
要回答你關於岩石的問題,我會建議所有可以碰撞到另一個東西的東西實現方法CollisonShape()返回collison.Shaper(例如Circle),你將用它來測試collison。這裏collison是你的軟件包的名稱。
// This interface is defined in the collison package.
// Any object that may collide must implement that method.
type Collider interface {
CollisonShape() Shaper
}
// This function defined in the collison package
// test if two Collider collide into each other.
func Collide(c1, c2 Collider) bool {
shape1, shape2 := c1.CollisonShape(), c2.CollisonShape()
...
}
// This is how you would define an object that can collide.
type Rock struct {
shape *collison.Circle
...
}
// Implements the Collider interface.
// The return type must be the same as in the interface.
func (r *Rock) CollisonShape() collison.Shaper {
return r.shape
}
正如你看到的,我們使用的方法來訪問岩石的科裏森形狀。這讓我們寫
if collison.Collide(rock, spaceCraft) {...}
這回答你的問題如何得到岩石的collison形狀。
如果您希望避免在Collide()函數中調用CollisonShape()方法,則必須直接傳遞collison.Shaper。
碰撞將在科裏森包被定義爲
func Collide(shape1, shape2 Shaper) bool {...}
方法,然後你會寫
if collison.Collide(rock.shape, spacecraft.shape) {...}
這種設計會稍微更有效,但付出的代價是少可讀的代碼,這是有經驗的Go程序員所憎惡的。
如果您希望Circle成爲嵌入式結構體,那麼您必須按以下方式對其進行定義。嵌入形狀可以節省Circle的分配時間和GC的一些工作。
type Rock struct {
shape collison.Circle
....
}
if collison.Collide(&rock.shape, &spacecraft.shape) {...}
如果你想使用匿名嵌入式結構,你再會寫
type Rock struct {
Circle
....
}
if collison.Collide(&rock.Circle, &spacecraft.Rectangle) {...}
正如你看到的,代碼變得越來越少可讀性,使用不太方便。形狀不再被抽象。使用匿名嵌入式結構應該僅限於極少數情況下才有意義。
通過使用最初建議的CollisonShape()方法,您可以輕鬆地將Rock結構更改爲此結構,而不會破壞任何代碼。
type Rock struct {
shape collison.Circle
...
}
func (r *Rock) CollisonShape() collison.Shaper {
return &r.shape
}
這現在使形狀和嵌入式結構。使用一種方法來獲得形狀,將岩石的內部實現與形狀的訪問分離開來。您可以更改Rock的內部實現,而無需在其他地方更改代碼。
這是Go不支持繼承的原因之一。它在基類和派生類之間創建了非常強大的依賴關係和耦合。經驗表明,人們經常爲代碼演變的耦合感到後悔。對象組合是首選,Go推薦和支持。
如果效率是您的目標,那麼每個對撞機應該有一個位置發生變化,並且邊界框的寬度和高度不會改變。您可以使用這些值爲邊界框重疊測試保存一些操作。但這是另一回事。
所以這個(https://play.golang.org/p/J5bvaEtLbM)會說明你的問題? – VonC 2015-03-13 18:27:28
有點。評論岩石的Shape()函數(然後使用圓圈)。我的問題是不能到達選擇的默認部分,但是如果我將一塊石頭傳遞給DoesShape() – user2089648 2015-03-13 19:15:16
那麼https://play.golang.org/p/rg_plLZMSM:'default :'部分是爲了說明'搖滾'沒有被檢測爲'圓形'成形者',即使'搖滾'具有'圓圈'作爲匿名字段。 – VonC 2015-03-13 19:21:31