2 回答

TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超9個(gè)贊
因?yàn)?code>type MainView View是“定義的類型”并且“不同于任何其他類型,包括創(chuàng)建它的類型。?”。
相反,您可以使用類型別名。type MainView = View
.
ViewInterface
但真正的問(wèn)題是和的設(shè)計(jì)Init()
。
Init()
寫得像一個(gè)類方法。Go 沒(méi)有類方法(或者,嚴(yán)格來(lái)說(shuō),類)。您創(chuàng)建結(jié)構(gòu)并在其上調(diào)用方法。簡(jiǎn)單的初始化可以馬上完成。
view?:=?View{?Width:?10,?Height:?10?}
如果您想定義一個(gè)方法來(lái)一致地初始化值,它將作用于現(xiàn)有結(jié)構(gòu)并且不返回任何內(nèi)容。
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
}
因?yàn)镮nit()需要一個(gè)指針,為了滿足ViewInterface你必須傳入指針。
func main() {
? ? view := View{}
? ? mv := MainView{}
? ? Render(&view, &mv)
}
但是Render()初始化對(duì)象到底在做什么呢?那應(yīng)該已經(jīng)完成了。應(yīng)該是渲染。接口應(yīng)該是關(guān)于通用功能的,而不考慮它是如何實(shí)現(xiàn)的。實(shí)現(xiàn) ViewInterface 的東西應(yīng)該已經(jīng)初始化了。
相反,您可能會(huì)說(shuō)ViewInterface必須有一個(gè)Render方法。
type ViewInterface interface{
? ? Render()
}
然后,View只要MainView它們實(shí)現(xiàn),就可以按照您喜歡的方式進(jìn)行結(jié)構(gòu)化Render()。
func (v View) Render() {
? ? fmt.Println("View!")
? ? fmt.Println(v)
}
func (mv MainView) Render() {
? ? fmt.Println("MainView!")
? ? fmt.Println(mv)
}
然后 aRender()可以列出實(shí)現(xiàn)ViewInterface和調(diào)用Render()它們中的每一個(gè)的事物。
func Render(views ...ViewInterface){
? for _, view := range views {
? ? ?view.Render()
? }
}
在傳入之前初始化它們?,F(xiàn)在不需要傳遞指針。
func main() {
? ? view := View{}
? ? view.Init()
? ? mv := MainView{}
? ? mv.Init()
? ? Render(view, mv)
}
最后,Markus 在評(píng)論中建議使用包來(lái)獲取類方法之類的東西。
# 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 包需要一點(diǎn)時(shí)間來(lái)適應(yīng),Go 對(duì)你的項(xiàng)目必須如何構(gòu)建有堅(jiān)定的想法。

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超3個(gè)贊
與 Java 和 C# 等主流語(yǔ)言相比,Go 具有不同的繼承模型。
為什么MianView 和View 不一樣?
因?yàn)樗鼈兊亩x不同。
InitMainView返回的函數(shù)MainView,而接口需要返回View。
方法簽名Init看起來(lái)很奇怪,它需要結(jié)構(gòu)實(shí)例,因?yàn)樗墙Y(jié)構(gòu)方法并返回相同結(jié)構(gòu)類型的新實(shí)例。
嘗試圍繞結(jié)構(gòu)的邏輯而不是結(jié)構(gòu)/生命周期來(lái)設(shè)計(jì)界面:
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 關(guān)注
- 195 瀏覽
添加回答
舉報(bào)