因为type MainView View 是"defined type" 和"is different from any other type, including the type it is created from."。
您可以改为使用type alias。 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()
}
}
在传入之前初始化它们。现在不需要传递指针了。
func main() {
view := View{}
view.Init()
mv := MainView{}
mv.Init()
Render(view, mv)
}
最后,Markus suggested in the comments 使用包来获取类方法之类的东西。
# 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 对如何构建项目有坚定的想法。 I suggest this tutorial.