3

我正在为我的应用程序使用 beego/orm。这里我有2个模型

type ModelA struct {
    Guid string `orm:"pk"`
    FiledA string
}

type ModelB struct {
    Guid string `orm:"pk"`
    FiledB string
}

我需要Save()为每个结构添加一个方法。一般来说,我可以创建一个Base结构并将其混合到ModelAandModelB中,但是 orm 不起作用。

有没有更好的解决方案?

编辑1:在此处提供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
}
4

2 回答 2

5

是的。定义一个接口。另外,讨厌吹毛求疵,虽然我很确定您在谈论嵌入,但 Go 中不存在“混合”概念。这是一些演示构造的伪代码。

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()那么我可能没有充分利用该功能。

于 2015-11-11T01:21:17.560 回答
0

不,你不能这样做,因为 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
}

小心,如果没有字段“guid”,它会恐慌

于 2017-05-14T14:57:30.463 回答