在 go 中覆盖结构标签

Override struct tags in go

我的项目中有一个可供 public 和管理员查看的实体。 public.

并非所有字段都可以访问

例如

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 方法中手动执行此操作?

一般来说,使用 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 结构。