一个在Golang中具有多个json表示的结构

Mat*_*cci 15 json go

我试图解决的问题是我有一个看起来像这样的社区模型

type Community struct {
    Name string
    Description string
    Sources []Source
    Popularity int
    FavoriteCount int
    Moderators []string
    Children []Community
    Tracks []Track
}
Run Code Online (Sandbox Code Playgroud)

社区拥有大量信息,有些情况下我只想返回部分描述,例如我是否返回趋势社区列表.在这种情况下,我只想返回

type Community struct {
    Name string
    Description string
    Popularity int
    FavoriteCount int
}
Run Code Online (Sandbox Code Playgroud)

我能想到这样做的唯一方法是创建一个只包含那些字段的新类型,并编写一个方便的方法来获取社区并返回该类型,但实际上创建一个新对象并按值复制这些字段,是否有更好的方法这样做的方法?

我知道json:"-"语法,但我不确定你是如何根据具体情况做的,因为我仍然需要有时返回完整的对象,也许是一个类型化的不同类型?

Kar*_*ung 15

编辑我的答案 - 找到了更好的方法:

这是一个很酷的方法:

http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/

涉及创建一种Masking结构.

这是文章中的示例:

type User struct {
    Email    string `json:"email"`
    Password string `json:"password"`
    // many more fields…
}

type omit *struct{}

type PublicUser struct {
    *User
    Password omit `json:"password,omitempty"`
}

// when you want to encode your user:
json.Marshal(PublicUser{
    User: user,
})
Run Code Online (Sandbox Code Playgroud)


fab*_*ioM 5

是的,据我所知,这是使用默认封送拆收器的唯一方法。唯一的其他选择是创建自己的 json.Marshaler 。

type Community struct {

}

type CommunityShort Community

func (key *Community) MarshalJSON() ([]byte, os.Error) {
  ...
}

func (key *Community) UnmarshalJSON(data []byte) os.Error {
 ...
}


func (key *CommunityShort) MarshalJSON() ([]byte, os.Error) {
  ...
}

func (key *CommunityShort) UnmarshalJSON(data []byte) os.Error {
 ...
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*bel 5

我开发了一个可以帮助你的图书馆:警长

您可以使用特殊标记注释结构字段,并调用Sheriff将给定结构转换为其子集.在那之后你可以打电话json.Marshal()或者你想要编组的其他任何东西.

您的示例将变得如此简单:

type Community struct {
    Name          string      `json:"name" groups:"trending,detail"`
    Description   string      `json:"description" groups:"trending,detail"`
    Sources       []Source    `json:"sources" groups:"detail"`
    Popularity    int         `json:"popularity" groups:"trending,detail"`
    FavoriteCount int         `json:"favorite_count" groups:"trending,detail"`
    Moderators    []string    `json:"moderators" groups:"detail"`
    Children      []Community `json:"children" groups:"detail"`
    Tracks        []Track     `json:"tracks" groups:"detail"`
}

communities := []Community{
    // communities
}

o := sheriff.Options{
    Groups: []string{"trending"},
}

d, err := sheriff.Marshal(&o, communities)
if err != nil {
    panic(err)
}

out, _ := json.Marshal(d)
Run Code Online (Sandbox Code Playgroud)