如何为在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 结构并将其混合到 ModelAModelB 中,但 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"