如何为在golang中具有一个公共字段的不同结构添加一种方法
How to add a method for different structs which have one common field in 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
中,但 orm 不起作用。
有没有更好的解决方案?
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
}
是的。定义一个接口。另外,讨厌挑剔,虽然我很确定你在谈论嵌入,但 Go 中不存在 'mixin' 概念。这是一些演示构造的伪代码。
type Savable interface {
Save()
}
// satisfies Savable for ModelA
func (a ModelA) Save() {
// do something
}
var i Savable
i = SomeMethodThatRetunsMyModel()
i.Save()
SomeOthermMethodThatAcceptsASavableAndCallesSave(i)
编辑:根据一些讨论,OP 可能想做如下的事情
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
的一个版本,在嵌入器中重新定义它,甚至在该方法中调用它,但是这样做并没有多大意义。如果您仍然必须静态引用嵌入类型,我会指出要避免嵌入。例如,如果我有 ModelA
嵌入 ModelC
并且在更广泛的范围内我必须做 ModelA.ModelC.SomeMethodThatIhaveToReferencExplicitlyToEnsureItsCalled()
那么我可能没有很好地利用该功能。
不可以,因为golang不支持继承。但是你可以像下面这样做:
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
}
注意,没有字段会出现panic "guid"
我正在为我的应用程序使用 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
中,但 orm 不起作用。
有没有更好的解决方案?
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
}
是的。定义一个接口。另外,讨厌挑剔,虽然我很确定你在谈论嵌入,但 Go 中不存在 'mixin' 概念。这是一些演示构造的伪代码。
type Savable interface {
Save()
}
// satisfies Savable for ModelA
func (a ModelA) Save() {
// do something
}
var i Savable
i = SomeMethodThatRetunsMyModel()
i.Save()
SomeOthermMethodThatAcceptsASavableAndCallesSave(i)
编辑:根据一些讨论,OP 可能想做如下的事情
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
的一个版本,在嵌入器中重新定义它,甚至在该方法中调用它,但是这样做并没有多大意义。如果您仍然必须静态引用嵌入类型,我会指出要避免嵌入。例如,如果我有 ModelA
嵌入 ModelC
并且在更广泛的范围内我必须做 ModelA.ModelC.SomeMethodThatIhaveToReferencExplicitlyToEnsureItsCalled()
那么我可能没有很好地利用该功能。
不可以,因为golang不支持继承。但是你可以像下面这样做:
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
}
注意,没有字段会出现panic "guid"