json 如何在 Golang 中合并两个结构?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40509575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I merge two structs in Golang?
提问by Dmitry Kapsamun
I have two json-marshallable anonymous structs.
我有两个 json-marshallable 匿名结构。
a := struct {
Name string `json:"name"`
}{"my name"}
b := struct {
Description string `json:"description"`
}{"my description"}
Is there any way to merge them into json to get something like that:
有什么方法可以将它们合并到 json 中以获得类似的东西:
{
"name":"my name",
"description":"my description"
}
回答by nothingmuch
You can embed both structs in another.
您可以将这两个结构嵌入另一个.
type name struct {
Name string `json:"name"`
}
type description struct {
Description string `json:"description"`
}
type combined struct {
name
description
}
The JSON package will treat embedded structs kind of like unions, but this can get clunky pretty quickly.
JSON 包会将嵌入的结构视为联合,但这很快就会变得笨拙。
回答by Franck Jeannin
It's a bit convoluted but I suppose you could do something like this:
这有点令人费解,但我想你可以这样做:
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))
回答by Elias Van Ootegem
Go is all about composition over inheritance. Sadly, you're using anonymous structs, but given that you're clearly trying to json marshal them, you're better of defining them as types:
Go 是关于组合而不是继承。可悲的是,您使用的是匿名结构,但鉴于您显然是在尝试对它们进行 json 编组,最好将它们定义为类型:
type name struct {
Name string `json:"name"`
}
type desc struct {
Description string `json:"description"`
}
You can initialize them in the same way as you're currently doing, but instead of struct{<fields>}{init}, you'll just write
您可以使用与当前相同的方式初始化它们,但struct{<fields>}{init}您只需编写
a := name{"foo"}
b := desc{"Description"}
You can then combine them in any way you like by writing:
然后,您可以通过编写以下内容以任何您喜欢的方式组合它们:
c := struct {
name
description
}{a, b}
One quirk (that might trip you up at first) you have to get used to when composing types like this is how you initialize the members. Say you decide to create a type that combines the other two structs:
在像这样组合类型时必须习惯的一个怪癖(一开始可能会让你绊倒)是初始化成员的方式。假设您决定创建一个结合其他两个结构的类型:
type foo struct {
name
description
}
You cannot initialize it like this:
你不能像这样初始化它:
o := foo{"Name value", "description value"}
Go will complain about you using type string as type name. You'll have to write something like this:
Go 会抱怨你使用类型 string 作为 type name。你必须写这样的东西:
o := foo{
name{"Name value"},
description{Description: "Description val"},//optional with field names
}
An in-line composite built using existing objects (cf c := struct{}{a, b}) does this already.
Depending on what you're trying to do, it sometimes is easier to write something like this:
使用现有对象 (cf c := struct{}{a, b})构建的内联组合已经做到了这一点。
根据您要尝试执行的操作,有时编写这样的内容会更容易:
func (s *MyCompositeType) CopyName(n name) {
s.Name = n.Name
//copy other fields
}
It makes life easier when you're nesting composite types several levels deep.
当您将复合类型嵌套到几层深时,它会让生活变得更轻松。
回答by Adrien Parrochia
You can merge two struct like this :
您可以像这样合并两个结构:
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) )
}

