如何在Golang中合并两个结构?

时间:2016-11-09 14:40:19

标签: json go struct merge

我有两个json-marshallable匿名结构。

a := struct {
    Name string `json:"name"`
}{"my name"}

b := struct {
    Description string `json:"description"`
}{"my description"}

有没有办法将它们合并到json中以获得类似的东西:

{
    "name":"my name",
    "description":"my description"
}

4 个答案:

答案 0 :(得分:10)

你可以embed both structs in another

type name struct {
    Name string `json:"name"`
}

type description struct {
    Description string `json:"description"`
}

type combined struct {
    name
    description
}

JSON包会将嵌入式结构视为类似联合,但这很快就会变得笨重。

答案 1 :(得分:7)

这有点令人费解,但我想你可以这样做:

    a := struct {
        Name string `json:"name"`
    }{"my name"}

    b := struct {
        Description string `json:"description"`
    }{"my description"}

    var m map[string]string

    ja, _ := json.Marshal(a)
    json.Unmarshal(ja, &m)
    jb, _ := json.Marshal(b)
    json.Unmarshal(jb, &m)

    jm, _ := json.Marshal(m)
    fmt.Println(string(jm))

答案 2 :(得分:4)

你可以像这样合并两个结构:

print(df)

    index                 Date Device Element  Sub_Element    Value
0  179593  2017-11-28 16:39:00      x       y   eth_txload        9
1  179594  2017-11-28 16:39:00      x       y   eth_rxload       30
2  179595  2017-11-28 16:39:00      x       y  eth_ip_addr  x.x.x.x
3  179596  2017-11-28 16:39:00      x       y  description   string

答案 3 :(得分:3)

Go是关于继承的组合。可悲的是,你正在使用匿名结构,但鉴于你明显试图将json编组,你最好将它们定义为类型:

type name struct {
    Name string `json:"name"`
}
type desc struct {
    Description string `json:"description"`
}

您可以按照与当前相同的方式初始化它们,但不是struct{<fields>}{init},而是只写

a := name{"foo"}
b := desc{"Description"}

然后您可以通过编写以任何方式将它们组合起来:

c := struct {
    name
    description
}{a, b}

一个怪癖(最初可能会让你失望)你必须习惯于在编写类似这样的类型时初始化成员。假设您决定创建一个结合了其他两个结构的类型:

type foo struct {
    name
    description
}

你无法像这样初始化它:

o := foo{"Name value", "description value"}

Go会抱怨您使用类型字符串作为类型name。你必须写这样的东西:

o := foo{
    name{"Name value"},
    description{Description: "Description val"},//optional with field names
}

使用现有对象构建的内嵌复合(cf c := struct{}{a, b})已经这样做了 根据你想要做的事情,有时候写这样的东西会更容易:

func (s *MyCompositeType) CopyName(n name) {
    s.Name = n.Name
    //copy other fields
}

当您将复合类型嵌套在几个深层时,它会让生活更轻松。