Как добавить метод для различных структур, которые имеют одно общее поле в golang
Я использую beego/orm для своего приложения. Здесь у меня есть 2 модели
type ModelA struct {
Guid string `orm:"pk"`
FiledA string
}
type ModelB struct {
Guid string `orm:"pk"`
FiledB string
}
Мне нужно добавить Save()
метод для каждой структуры. В общем, я могу создать Base
структурировать и смешать в ModelA
а также ModelB
, но форма не будет работать.
Есть ли лучшее решение?
edit1: Предоставление Save()
код здесь, чтобы сделать вопрос более ясным
func (this *ModelA) Save() error {
o := orm.NewOrm()
guid := guidlib.Generate()
this.Guid = guid
_, err := o.Insert(this)
return err
}
func (this *ModelB) Save() error {
o := orm.NewOrm()
guid := guidlib.Generate()
this.Guid = guid
_, err := o.Insert(this)
return err
}
2 ответа
Да. Определить интерфейс. Кроме того, ненавижу придирки, хотя я уверен, что вы говорите о встраивании, в Go нет концепции "смешивания". Вот некоторый псевдокод, демонстрирующий конструкции.
type Savable interface {
Save()
}
// satisfies Savable for ModelA
func (a ModelA) Save() {
// do something
}
var i Savable
i = SomeMethodThatRetunsMyModel()
i.Save()
SomeOthermMethodThatAcceptsASavableAndCallesSave(i)
РЕДАКТИРОВАТЬ: на основе некоторых дискуссий кажется, что ОП, вероятно, хочет сделать что-то вроде ниже
type ModelA struct {
ModelC
FiledA string
}
type ModelB struct {
ModelC
FiledB string
}
type ModelC struct {
Guid string `orm:"pk"`
}
func (this ModelC) Save() error {
o := orm.NewOrm()
guid := guidlib.Generate()
this.Guid = guid
_, err := o.Insert(this)
return err
}
Тем не менее, обратите внимание, что o.Insert(this)
не собирается вставлять поля, которые не определены на ModelC
, Как я уже упоминал в своем комментарии ниже, тип структуры наследования, который может использоваться там, где модели A и B будут переопределены Save
вызов метода базовых классов заранее не очень хорошо работает в Go.
Правила разрешения методов со встроенными типами не совсем понятны и могут сбивать с толку. Вы можете определить одну версию Save
во встроенных структурах переопределите его в embedor и даже вызовите его в этом методе, однако делать это не имеет особого смысла. Я бы хотел избежать встраивания, если вам все равно придется статически ссылаться на встроенный тип. Например, если у меня есть ModelA
вложения ModelC
и в более широком смысле я должен сделать ModelA.ModelC.SomeMethodThatIhaveToReferencExplicitlyToEnsureItsCalled()
тогда я, вероятно, плохо использую эту функцию.
Нет, вы не можете сделать это, потому что Голанг не поддерживает наследование. Но вы можете сделать что-то вроде этого:
func Save(obj interface{}) error {
o := orm.NewOrm()
guid := guidlib.Generate()
r := reflect.ValueOf(obj)
f := reflect.Indirect(r).FieldByName("Guid")
f.setString(guid)
_, err := o.Insert(obj)
return err
}
Будьте осторожны, будет паника, если нет поля "guid"