如何将映射嵌入到结构中,使其具有平面 json 表示
How to embed a map into a struct so that it has a flat json representation
为了创建类似 table 的结构,我在之前的应用程序中将我的行数据序列化为以下格式:
{ "key1": "...", "key2": "...", "15/04": 1.3, "15/05": 1.2, .... "17/08": 0.8 }
现在我正在尝试用Go重写它,以便通过实践经验学习这门语言。在 Go 中,可以通过将两个结构嵌入到另一个结构中来将它们组合在一起。从该结构中编组的 json 将具有平面结构,即生成的 json 对象将具有第一个和第二个结构的字段的并集,而无需嵌套。这是一个例子:https://play.golang.org/p/jbJykip7pw (from http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/)
我想我也可以将映射嵌入到结构中,这样我就可以使用以下类型定义在 json 之上编组:
type Row struct {
key1 string
key2 string
RowData
}
type RowData map[string]float64
...
func main() {
row := Row{
"...",
"...",
RowData{
"15/04": 1.3, "15/05": 1.2, .... "17/08": 0.8,
},
}
}
但这在我的 'Row' 对象中创建了一个字段 'RowData' 字段,而不是将 RowData 中的条目附加到我想要的平面 json 对象中:
{ "key1": "...", "key2": "...", "RowData": { "15/04": 1.3, "15/05": 1.2, .... "17/08": 0.8 } }
我想知道,是否有一种方法可以将映射或切片嵌入到结构中,以便生成的 json 对象是扁平的,而无需在类型 [=15] 上定义 MarshalJSON
函数=]?
简短的回答是否定的。该语言不允许您在结构中嵌入任何一种类型(切片或映射)。
只需使用一个 map[string]interface{}
。处理 "key1" 和 "key2" 的值是字符串而其他所有内容都是其他地方的浮点数这一事实。这确实是您获得该输出的唯一方式。您可以使问题变得更复杂,超出这个范围(比如转换成更像您的类型或其他类型),但是如果您不愿意实施 MarshalJSON
唯一会产生您想要的结果的模型是map[string]interface{}
我知道已经有一个可接受的答案,但实际上你可以获得指定的 "desired flat json object."
"RowData" 不完全是 map[string]float
;获取它的类型将产生 "main.RowData" (如果它在包 main 中)。它可以嵌入到结构中。举个例子,改编自原文 post:
package main
import (
"encoding/json"
"fmt"
)
type Row struct {
Key1 string
Key2 string
RowData
}
type RowData map[string]float64
func main() {
row := Row{
RowData: make(map[string]float64),
}
row.RowData["15/04"] = 1.3
row.RowData["15/05"] = 1.2
row.RowData["17/08"] = 0.8
row.Key1 = "value one"
row.Key2 = "value two"
flatJSON, _ := json.Marshal(row)
fmt.Println(string(flatJSON))
}
这将产生:
{"Key1":"value one","Key2":"value two","RowData":{"15/04":1.3,"15/05":1.2,"17/08":0.8}}
字段名称必须大写才能导出,但您可以使用结构标签使它们与问题中指定的确切字符串匹配。
为了创建类似 table 的结构,我在之前的应用程序中将我的行数据序列化为以下格式:
{ "key1": "...", "key2": "...", "15/04": 1.3, "15/05": 1.2, .... "17/08": 0.8 }
现在我正在尝试用Go重写它,以便通过实践经验学习这门语言。在 Go 中,可以通过将两个结构嵌入到另一个结构中来将它们组合在一起。从该结构中编组的 json 将具有平面结构,即生成的 json 对象将具有第一个和第二个结构的字段的并集,而无需嵌套。这是一个例子:https://play.golang.org/p/jbJykip7pw (from http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/)
我想我也可以将映射嵌入到结构中,这样我就可以使用以下类型定义在 json 之上编组:
type Row struct {
key1 string
key2 string
RowData
}
type RowData map[string]float64
...
func main() {
row := Row{
"...",
"...",
RowData{
"15/04": 1.3, "15/05": 1.2, .... "17/08": 0.8,
},
}
}
但这在我的 'Row' 对象中创建了一个字段 'RowData' 字段,而不是将 RowData 中的条目附加到我想要的平面 json 对象中:
{ "key1": "...", "key2": "...", "RowData": { "15/04": 1.3, "15/05": 1.2, .... "17/08": 0.8 } }
我想知道,是否有一种方法可以将映射或切片嵌入到结构中,以便生成的 json 对象是扁平的,而无需在类型 [=15] 上定义 MarshalJSON
函数=]?
简短的回答是否定的。该语言不允许您在结构中嵌入任何一种类型(切片或映射)。
只需使用一个 map[string]interface{}
。处理 "key1" 和 "key2" 的值是字符串而其他所有内容都是其他地方的浮点数这一事实。这确实是您获得该输出的唯一方式。您可以使问题变得更复杂,超出这个范围(比如转换成更像您的类型或其他类型),但是如果您不愿意实施 MarshalJSON
唯一会产生您想要的结果的模型是map[string]interface{}
我知道已经有一个可接受的答案,但实际上你可以获得指定的 "desired flat json object."
"RowData" 不完全是 map[string]float
;获取它的类型将产生 "main.RowData" (如果它在包 main 中)。它可以嵌入到结构中。举个例子,改编自原文 post:
package main
import (
"encoding/json"
"fmt"
)
type Row struct {
Key1 string
Key2 string
RowData
}
type RowData map[string]float64
func main() {
row := Row{
RowData: make(map[string]float64),
}
row.RowData["15/04"] = 1.3
row.RowData["15/05"] = 1.2
row.RowData["17/08"] = 0.8
row.Key1 = "value one"
row.Key2 = "value two"
flatJSON, _ := json.Marshal(row)
fmt.Println(string(flatJSON))
}
这将产生:
{"Key1":"value one","Key2":"value two","RowData":{"15/04":1.3,"15/05":1.2,"17/08":0.8}}
字段名称必须大写才能导出,但您可以使用结构标签使它们与问题中指定的确切字符串匹配。