在go中覆盖struct标签

时间:2016-08-22 10:21:26

标签: json go struct dry

我的项目中有一个可由公众和管理员查看的实体。并非公开都可以访问所有字段。

例如

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"`
}

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

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
}

但是如果我需要向我的实体添加新字段,我需要在3个地方添加它。在结构本身中,在PublicFooPublic方法中 这似乎是DRY的原则。什么是正确的,惯用的解决方案?我可以定义FooPublic,以便覆盖所需字段的标记吗?或者至少有一种将相应字段从一个结构复制到另一个结构的好方法,所以我不需要在Public方法中手动执行此操作?

1 个答案:

答案 0 :(得分:2)

通常,使用embedding可以避免重复。您的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结构。