在Go语言中覆盖结构体标签

3

我在项目中有一个实体,公众和管理员都可以查看。但不是所有字段都应该被公众访问。

例如:

type Foo struct {
    Id        bson.ObjectId `json:"id" bson:"_id"`
    DateAdded time.Time     `json:"date_added" bson:"date_added"`
    Bar       string `json:"bar" bson:"bar"`      
    AdminOnly string        `json:"admin_only" bson:"admin_only"`
}

仅管理员可见的字段应仅对管理员可见。 目前,当请求来自公共时,我调用单独的方法,将每个需要的字段复制到新结构中。

type FooPublic struct {
    Id        bson.ObjectId `json:"id" bson:"_id"`
    DateAdded time.Time     `json:"date_added" bson:"date_added"`
    Bar       string `json:"bar" bson:"bar"`
}

func (f *Foo) Public() (res FooPublic) {
    res = FooPublic{
        Id: f.Id,
        DateAdded: f.DateAdded,
        Bar:f.Bar,
    }
    return
}

但是,如果我需要向实体添加新字段,则需要在三个位置上进行添加。在结构本身中,在PublicFooPublic方法中。
这似乎违反了DRY原则。这里正确的、惯用的解决方案是什么?我能否定义FooPublic,使其覆盖所需字段的标签?或者可能有一种好的方式可以从一个结构复制相应的字段到另一个结构,这样我就不需要在Public方法中手动完成这个操作了吗?

1个回答

3

通常可以通过使用嵌入来避免这种重复。您的Foo类型应该嵌入FooPublic

type FooPublic struct {
    Id        bson.ObjectId `json:"id" bson:"_id"`
    DateAdded time.Time     `json:"date_added" bson:"date_added"`
    Bar       string        `json:"bar" bson:"bar"`      
}

type Foo struct {
    FooPublic
    AdminOnly string `json:"admin_only" bson:"admin_only"`
}

func (f *Foo) Public() FooPublic {
    return f.FooPublic
}

但是如果有人能够调用 Foo.Public(),那么这个人已经拥有了 Foo*Foo 值(因此可以访问导出的 AdminOnly 字段),那么这有什么意义呢?

更好的解决方案是使用接口,而不是暴露 Foo 结构。


谢谢。那似乎对我来说是个可行的解决方案。当我提及公共和管理员访问时,我的意思是应用用户的角色,因此根据用户角色,我会返回Foo或FooPublic作为JSON。 - user6743038
是的,你根本不需要那个 Public() 方法。如果你有 type Foo struct { FooPublic; AdminOnly string; },那么你可以通过 foo.FooPublic 来访问 var foo Foo 的嵌入式 FooPublic 值。 - Jesse Amano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接