
go 的 json.marshal 要求 map 的值类型必须统一或能被 json 编码器识别,因此需使用 map[string]interface{} 代替 map[string]string,以支持字符串、整数、布尔值等混合类型。
go 的 json.marshal 要求 map 的值类型必须统一或能被 json 编码器识别,因此需使用 map[string]interface{} 代替 map[string]string,以支持字符串、整数、布尔值等混合类型。
在 Go 中,JSON 序列化依赖于标准库 encoding/json 包,而该包对 map 类型有明确的类型约束:键必须是字符串(string),值必须是可 JSON 编码的类型(如 string、int、float64、bool、nil、切片、其他 map[string]interface{} 或实现了 json.Marshaler 接口的自定义类型)。
你遇到的编译错误:
prog.go:17: cannot use 2 (type int) as type string in map value
正是因为声明了 map[string]string,却试图将整数 2 赋值给其中的 "version" 键——Go 是强类型语言,不允许隐式类型转换。
✅ 正确做法是使用 map[string]interface{}:
package main
import (
"encoding/json"
"fmt"
)
func main() {
// ✅ 支持混合类型:string、int、bool 等
mapD := map[string]interface{}{
"deploy_status": "public",
"status": "live",
"version": 2,
"is_active": true,
"tags": []string{"v1.2", "prod"},
"metadata": map[string]interface{}{"retry_count": 3},
}
mapB, err := json.Marshal(mapD)
if err != nil {
panic(err) // 实际项目中请妥善处理错误
}
fmt.Println(string(mapB))
// 输出:{"deploy_status":"public","is_active":true,"metadata":{"retry_count":3},"status":"live","tags":["v1.2","prod"],"version":2}
}
? 关键注意事项:
- interface{} 是 Go 中的空接口,可容纳任意类型,但 json.Marshal 仅对上述「JSON 可表示类型」安全支持;若传入不支持的类型(如函数、channel、未导出字段的结构体),会返回 json.UnsupportedTypeError。
- 若需更高类型安全性与性能,推荐定义结构体(struct)并使用字段标签(如 json:"version"),尤其适用于固定 schema 的 API 请求/响应。
- 避免在生产环境中忽略 json.Marshal 的错误(如 _ := json.Marshal(...)),JSON 编码失败可能源于嵌套不可序列化值,应始终检查 err。
? 小技巧:若需将 []interface{}(如切片)或嵌套 map[string]interface{} 转为 JSON,方式完全一致——只要所有层级均满足 JSON 编码要求即可。
综上,map[string]interface{} 是 Go 中灵活构建动态 JSON 数据的标准方式,兼顾简洁性与兼容性,是 API 客户端构造请求体的常用实践。











