Поскольку 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)
}
. Затем Render()
может взять список вещей, которые реализуют 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)
}
Наконец, Маркус предложил в комментариях используя пакет, чтобы получить что-то вроде методов класса.
# 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 имеет твердые идеи о том, как должен быть структурирован ваш проект. Я предлагаю этот урок .