2 回答

TA貢獻1860條經驗 獲得超9個贊
因為type MainView View
是“定義的類型”并且“不同于任何其他類型,包括創建它的類型。?”。
相反,您可以使用類型別名。type MainView = View
.
ViewInterface
但真正的問題是和的設計Init()
。
Init()
寫得像一個類方法。Go 沒有類方法(或者,嚴格來說,類)。您創建結構并在其上調用方法。簡單的初始化可以馬上完成。
view?:=?View{?Width:?10,?Height:?10?}
如果您想定義一個方法來一致地初始化值,它將作用于現有結構并且不返回任何內容。
type ViewInterface interface{
? ? Init()
}
type View struct{
? ? Width? int
? ? Height int
}
func (v *View) Init() {
? ? v.Width = 10
? ? v.Height = 10
}
view := View{}
view.Init()
然后MainView還可以定義Init().
type MainView struct {
? ? X int
? ? Y int
}
type (mv *MainView) Init() {
? ? mv.X = 23
? ? mv.Y = 42
}
因為Init()需要一個指針,為了滿足ViewInterface你必須傳入指針。
func main() {
? ? view := View{}
? ? mv := MainView{}
? ? Render(&view, &mv)
}
但是Render()初始化對象到底在做什么呢?那應該已經完成了。應該是渲染。接口應該是關于通用功能的,而不考慮它是如何實現的。實現 ViewInterface 的東西應該已經初始化了。
相反,您可能會說ViewInterface必須有一個Render方法。
type ViewInterface interface{
? ? Render()
}
然后,View只要MainView它們實現,就可以按照您喜歡的方式進行結構化Render()。
func (v View) Render() {
? ? fmt.Println("View!")
? ? fmt.Println(v)
}
func (mv MainView) Render() {
? ? fmt.Println("MainView!")
? ? fmt.Println(mv)
}
然后 aRender()可以列出實現ViewInterface和調用Render()它們中的每一個的事物。
func Render(views ...ViewInterface){
? for _, view := range views {
? ? ?view.Render()
? }
}
在傳入之前初始化它們?,F在不需要傳遞指針。
func main() {
? ? view := View{}
? ? view.Init()
? ? mv := MainView{}
? ? mv.Init()
? ? Render(view, mv)
}
最后,Markus 在評論中建議使用包來獲取類方法之類的東西。
# viewtest/main.go
package main
import(
? ? "log"
? ? "viewtest/view"
)
func main() {
? ? v := view.New()
? ? log.Printf("%#v", v)
}
# viewtest/view/view.go
package view
type View struct {
? ? Width? int
? ? Height int
}
func New() View {
? ? return View{Width: 10, Height: 10}
}
Go 包需要一點時間來適應,Go 對你的項目必須如何構建有堅定的想法。

TA貢獻1798條經驗 獲得超3個贊
與 Java 和 C# 等主流語言相比,Go 具有不同的繼承模型。
為什么MianView 和View 不一樣?
因為它們的定義不同。
InitMainView返回的函數MainView,而接口需要返回View。
方法簽名Init看起來很奇怪,它需要結構實例,因為它是結構方法并返回相同結構類型的新實例。
嘗試圍繞結構的邏輯而不是結構/生命周期來設計界面:
type ViewInterface interface{
Render()
}
type MainView View
func (m MainView) Render() {
// do something
}
type AnotherView
func (m AnotherView) Render() {
// do something else
}
func Render(views ...ViewInterface){
for _, view := range views {
view.Render()
}
}
- 2 回答
- 0 關注
- 190 瀏覽
添加回答
舉報