Обеспечение встроенных структур реализует интерфейс без внесения двусмысленности
Я пытаюсь очистить свою кодовую базу, улучшив определение интерфейсов и используя встроенные структуры для повторного использования функциональности. В моем случае у меня есть много типов сущностей, которые могут быть связаны с различными объектами. Я хочу определить интерфейсы, которые отражают требования и структуры, которые реализуют интерфейсы, которые затем могут быть встроены в объекты.
// All entities implement this interface
type Entity interface {
Identifier()
Type()
}
// Interface for entities that can link Foos
type FooLinker interface {
LinkFoo()
}
type FooLinkerEntity struct {
Foo []*Foo
}
func (f *FooLinkerEntity) LinkFoo() {
// Issue: Need to access Identifier() and Type() here
// but FooLinkerEntity doesn't implement Entity
}
// Interface for entities that can link Bars
type BarLinker interface {
LinkBar()
}
type BarLinkerEntity struct {
Bar []*Bar
}
func (b *BarLinkerEntity) LinkBar() {
// Issues: Need to access Identifier() and Type() here
// but BarLinkerEntity doesn't implement Entity
}
Поэтому моей первой мыслью было, чтобы FooLinkerEntity и BarLinkerEntity просто реализовали интерфейс Entity.
// Implementation of Entity interface
type EntityModel struct {
Id string
Object string
}
func (e *EntityModel) Identifier() { return e.Id }
func (e *EntityModel) Type() { return e.Type }
type FooLinkerEntity struct {
EntityModel
Foo []*Foo
}
type BarLinkerEntity struct {
EntityModel
Bar []*Bar
}
Однако это приводит к ошибке неоднозначности для любых типов, которые могут связывать как Foos, так и Bars.
// Baz.Identifier() is ambiguous between EntityModel, FooLinkerEntity,
// and BarLinkerEntity.
type Baz struct {
EntityModel
FooLinkerEntity
BarLinkerEntity
}
Какой правильный Go способ структурировать этот тип кода? Я просто делаю утверждение типа вLinkFoo()
а такжеLinkBar()
чтобы добраться доIdentifier()
а такжеType()
? Есть ли способ получить эту проверку во время компиляции, а не во время выполнения?