json - 如何在Go中将具有嵌入式struct字段的结构编码(marshal)为平面JSON对象?

标签 json go struct encoding

package main

import (
    "encoding/json"
    "fmt"
)

type City struct {
    City string `json:"City"`
    Size int        `json:"Size"`
}

type Location struct {
    City City
    State string `json:"State"`
}

func main() {
    city := City{City: "San Francisco", Size: 8700000}
    loc := Location{}
    loc.State = "California"
    loc.City = city
    js, _ := json.Marshal(loc)
    fmt.Printf("%s", js)
}

输出以下内容:
{"City":{"City":"San Francisco","Size":8700000},"State":"California"}

我想要的预期输出是:
{"City":"San Francisco","Size":8700000,"State":"California"}

我已阅读此blog post进行自定义JSON编码,但似乎无法使其与另一个嵌入式结构一起使用。

我尝试通过定义自定义MarshalJSON函数来展平该结构,但仍得到相同的嵌套输出:
func (l *Location) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
            City string `json:"City"`
            Size int    `json:"Size"`
            State string `json:"State"`
    }{
        City: l.City.City,
        Size: l.City.Size,
        State:   l.State,
    })
}

最佳答案

使用匿名字段来展平JSON输出:

type City struct {
    City string `json:"City"`
    Size int        `json:"Size"`
}

type Location struct {
    City     // <-- anonymous field has type, but no field name
    State string `json:"State"`
}

该问题中忽略了MarshalJSON方法,因为代码对Location值进行了编码,但是MarshalJSON方法是使用指针接收器声明的。通过编码*Location进行修复。
js, _ := json.Marshal(&loc)  // <-- note &

关于json - 如何在Go中将具有嵌入式struct字段的结构编码(marshal)为平面JSON对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58106307/

相关文章:

c - C 中结构体指针指向哪个地址?

javascript - 带有 $http 注入(inject) angularjs 的自定义指令

javascript - 在 sessionStorage.setitem 中存储值时仅获取最后输入的值

json - 如何从数组中获取特定值?

http - net.Dialer#KeepAlive和http.Transport#IdleTimeout有什么区别?

http - 为什么 "http.Get()"方法在 go 中抛出致命异常?

javascript - 设置全局变量但未得到预期结果

compiler-errors - Google Go 错误 - "cannot make type"

go - 如何调用作为接口(interface)传递的对象的嵌入式结构方法?

c - malloc 无法为队列中的结构创建空间