我可以在 Golang 中编组结构时跳过 json 标记吗?
Can I skip a json tag while Marshalling a struct in Golang?
我有一个场景,我想在 Golang 中编组结构时跳过 json 标记。那可能吗?如果可以,我该如何实现?
例如我得到这个json:
{"Employee":{"Interface":{"Name":"xyz", "Address":"abc"}}}
但我希望 json 是:
{"Employee":{"Name":"xyz", "Address":"abc"}}
您可以使用匿名结构
type Employee struct {
Interface Interface
}
type Interface struct {
Name string
Address string
}
func main() {
a := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
b := struct {
Employee Interface
}{
Employee: a.Interface,
}
jsonResult, _ := json.Marshal(b)
fmt.Println(string(jsonResult)) // {"Employee":{"Name":"xyz","Address":"abc"}}
}
如果 Interface
字段的类型 不是 实际接口而是结构类型,那么您可以嵌入该字段,这会将嵌入结构的字段提升为 Employee
并将其编组为 JSON 将为您提供所需的输出。
type Employee struct {
Interface // embedded field
}
type Interface struct {
Name string
Address string
}
func main() {
type Output struct{ Employee Employee }
e := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
out, err := json.Marshal(Output{e})
if err != nil {
panic(err)
}
fmt.Println(string(out))
}
https://play.golang.org/p/s5SFfDzVwPN
如果 Interface
字段的类型 是 实际的接口类型,那么嵌入将无济于事,相反,您可以让 Employee
类型实现 json.Marshaler
界面并自定义生成的 JSON.
例如,您可以执行以下操作:
type Employee struct {
Interface Interface `json:"-"`
}
func (e Employee) MarshalJSON() ([]byte, error) {
type E Employee
obj1, err := json.Marshal(E(e))
if err != nil {
return nil, err
}
obj2, err := json.Marshal(e.Interface)
if err != nil {
return nil, err
}
// join the two objects by dropping '}' from obj1 and
// dropping '{' from obj2 and then appending obj2 to obj1
//
// NOTE: if the Interface field was nil, or it contained a type
// other than a struct or a map or a pointer to those, then this
// will produce invalid JSON and marshal will fail with an error.
// If you expect those cases to occur in your program you should
// add some logic here to handle them.
return append(obj1[:len(obj1)-1], obj2[1:]...), nil
}
我有一个场景,我想在 Golang 中编组结构时跳过 json 标记。那可能吗?如果可以,我该如何实现?
例如我得到这个json:
{"Employee":{"Interface":{"Name":"xyz", "Address":"abc"}}}
但我希望 json 是:
{"Employee":{"Name":"xyz", "Address":"abc"}}
您可以使用匿名结构
type Employee struct {
Interface Interface
}
type Interface struct {
Name string
Address string
}
func main() {
a := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
b := struct {
Employee Interface
}{
Employee: a.Interface,
}
jsonResult, _ := json.Marshal(b)
fmt.Println(string(jsonResult)) // {"Employee":{"Name":"xyz","Address":"abc"}}
}
如果 Interface
字段的类型 不是 实际接口而是结构类型,那么您可以嵌入该字段,这会将嵌入结构的字段提升为 Employee
并将其编组为 JSON 将为您提供所需的输出。
type Employee struct {
Interface // embedded field
}
type Interface struct {
Name string
Address string
}
func main() {
type Output struct{ Employee Employee }
e := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
out, err := json.Marshal(Output{e})
if err != nil {
panic(err)
}
fmt.Println(string(out))
}
https://play.golang.org/p/s5SFfDzVwPN
如果 Interface
字段的类型 是 实际的接口类型,那么嵌入将无济于事,相反,您可以让 Employee
类型实现 json.Marshaler
界面并自定义生成的 JSON.
例如,您可以执行以下操作:
type Employee struct {
Interface Interface `json:"-"`
}
func (e Employee) MarshalJSON() ([]byte, error) {
type E Employee
obj1, err := json.Marshal(E(e))
if err != nil {
return nil, err
}
obj2, err := json.Marshal(e.Interface)
if err != nil {
return nil, err
}
// join the two objects by dropping '}' from obj1 and
// dropping '{' from obj2 and then appending obj2 to obj1
//
// NOTE: if the Interface field was nil, or it contained a type
// other than a struct or a map or a pointer to those, then this
// will produce invalid JSON and marshal will fail with an error.
// If you expect those cases to occur in your program you should
// add some logic here to handle them.
return append(obj1[:len(obj1)-1], obj2[1:]...), nil
}