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

Dmi*_*mun 7 merge json struct go

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

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

b := struct {
    Description string `json:"description"`
}{"my description"}
Run Code Online (Sandbox Code Playgroud)

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

{
    "name":"my name",
    "description":"my description"
}
Run Code Online (Sandbox Code Playgroud)

not*_*uch 11

您可以将两个结构嵌入另一个结构中.

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

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

type combined struct {
    name
    description
}
Run Code Online (Sandbox Code Playgroud)

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


Fra*_*nin 10

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

    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))
Run Code Online (Sandbox Code Playgroud)


Eli*_*gem 7

Go 是关于组合而不是继承。可悲的是,您使用的是匿名结构,但鉴于您显然是在尝试对它们进行 json 编组,最好将它们定义为类型:

type name struct {
    Name string `json:"name"`
}
type desc struct {
    Description string `json:"description"`
}
Run Code Online (Sandbox Code Playgroud)

您可以使用与当前相同的方式初始化它们,但struct{<fields>}{init}您只需编写

a := name{"foo"}
b := desc{"Description"}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过编写以下内容以任何您喜欢的方式组合它们:

c := struct {
    name
    description
}{a, b}
Run Code Online (Sandbox Code Playgroud)

像这样组合类型时必须习惯的一个怪癖(一开始可能会让你绊倒)是初始化成员的方式。假设您决定创建一个结合其他两个结构的类型:

type foo struct {
    name
    description
}
Run Code Online (Sandbox Code Playgroud)

你不能像这样初始化它:

o := foo{"Name value", "description value"}
Run Code Online (Sandbox Code Playgroud)

Go 会抱怨你使用类型 string 作为 type name。你必须写这样的东西:

o := foo{
    name{"Name value"},
    description{Description: "Description val"},//optional with field names
}
Run Code Online (Sandbox Code Playgroud)

使用现有对象 (cf c := struct{}{a, b})构建的内联组合已经做到了这一点。
根据您要尝试执行的操作,有时编写这样的内容会更容易:

func (s *MyCompositeType) CopyName(n name) {
    s.Name = n.Name
    //copy other fields
}
Run Code Online (Sandbox Code Playgroud)

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


Adr*_*hia 5

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

package main

import (
    "fmt"
    "encoding/json"
)


type b struct {
    Name string  `json:"name"`
    Description string
    Url string
}

type a struct {
    *b
    MimeType string  `json:"mimeType"`
}

func main() {
    bc := b{"test", "testdecription", "testurl"}
    ac := a{nil, "jpg"}

    ac.b = &bc

    js, _ := json.Marshal(ac)

    fmt.Println(string(js) )
}
Run Code Online (Sandbox Code Playgroud)