
本文介绍如何将形如 `[{“key1″:”val1”},{“key2″:”val2”}]` 的 json 数组解析为一个统一的 `map[String]string`,涵盖解码流程、类型选择、遍历合并技巧及常见注意事项。
在 go 中处理 jsON 数据时,若原始数据是以多个独立对象组成的数组形式存在(例如 [{“Cat”:”small animal”},{“Cow”:”Big animal”}]),而非单个扁平对象(如 {“Cat”:”small animal”,”Cow”:”Big animal”}),则不能直接 json.Unmarshal 到 map[string]string——因为 json 格式不匹配:前者是 JSON 数组([]),后者是 JSON 对象({})。
正确的做法是分两步解析:
以下是完整可运行示例:
package main import ( "encoding/json" "fmt" "log" ) func main() { // 原始 JSON 必须是数组格式:用方括号 [] 包裹多个对象 jsonText := []byte(`[ {"Cat": "small animal"}, {"Cow": "Big animal"}, {"Dog": "loyal pet"} ]`) var rawList []map[string]string if err := json.Unmarshal(jsonText, &rawList); err != nil { log.Fatal("JSON 解析失败:", err) } // 合并为单个 map resultMap := make(map[string]string) for _, item := range rawList { for key, value := range item { resultMap[key] = value // 若存在重复 key,后出现的值会覆盖前者 } } fmt.Printf("合并后的字典: %+vn", resultMap) // 输出: 合并后的字典: map[Cat:small animal Cow:Big animal Dog:loyal pet] }
✅ 关键说明:
- 输入 JSON 必须是合法数组(以 [ 开头、] 结尾),否则 json.Unmarshal 会报错 invalid character … expecting [。
- 使用 []map[string]string 是最直观且安全的中间类型——它明确表达了“多个无序键值对对象的集合”。
- 若原始数据实际是 {…} 包裹(即顶层为对象而非数组),需先确认其结构是否为「带字段名的包装对象」(如 {“data”: […]}),此时应定义结构体解析,而非强行转为 []map。
- 合并逻辑中未做 key 冲突校验;如业务要求检测重复键,可在内层循环添加 if _, exists := resultMap[key]; exists { /* 处理冲突 */ }。
? 进阶建议:
- 对于大规模数据,可考虑使用 json.Decoder 流式解析避免内存峰值;
- 若键类型不固定(如含数字或空格),建议统一用 map[string]Interface{} + 类型断言,再转换为目标类型;
- 生产环境推荐配合 json.RawMessage 或自定义 UnmarshalJSON 方法提升健壮性与可维护性。
通过该模式,你可灵活应对各类“分散式键值对集合”的 JSON 场景,兼顾简洁性与可扩展性。