
本文讲解如何将 JSON 中的字符串数组(如 "to": ["a@example.com", "b@example.com"])准确反序列化到 Go 结构体中,重点纠正 []string 与 map[string]string 的误用,并提供可直接运行的结构体定义与解析示例。
本文讲解如何将 json 中的字符串数组(如 `"to": ["a@example.com", "b@example.com"]`)准确反序列化到 go 结构体中,重点纠正 `[]string` 与 `map[string]string` 的误用,并提供可直接运行的结构体定义与解析示例。
在 Go 语言中,JSON 数组(如 "to": ["user1@example.com", "user2@example.com"])必须映射为 Go 的切片(slice),而非 map 或单个字符串。常见误区是将数组误认为对象而使用 map[string]string(适用于键值对)或 string(仅能接收单个字符串),导致 json.Unmarshal 静默失败或返回 nil 值。
正确的做法是:将 JSON 数组字段(无论长度是否固定)声明为 []string 类型,并确保 JSON tag 的 key 名称严格匹配(注意大小写)。例如,原始 JSON 中字段名为 "to" 和 "cc"(全小写),因此结构体字段的 json tag 必须写作 `json:"to"` 和 `json:"cc"`,而非 "To" 或 "CC"。
以下是修正后的完整结构体定义,已通过实际 JSON 示例验证:
type emailData struct {
Body struct {
Template string `json:"template"`
Params map[string]string `json:"params"`
} `json:"body"`
To []string `json:"to"` // ✅ 正确:JSON array → []string
CC []string `json:"cc"` // ✅ 正确:支持任意长度字符串数组
ReplyTo struct {
Email string `json:"email"`
Name string `json:"name"`
} `json:"replyTo"` // 注意:JSON 字段为 "replyTo",需显式指定 tag
BCC string `json:"bcc"`
Subject string `json:"subject"`
}
? 关键注意事项:
- Go 的结构体字段首字母必须大写(导出)才能被
json包访问; - JSON tag 名称区分大小写,必须与请求中的字段名完全一致(如
"to"≠"To"); -
ReplyTo是嵌套对象,需为其添加json:"replyTo"tag,否则默认按字段名ReplyTo查找(JSON 中不存在该 key); -
BCC字段在示例 JSON 中为单个字符串,使用string类型正确;若未来可能变为数组,应改为[]string并做兼容性判断。
你可直接将该结构体用于 HTTP 请求体解析,例如在 Gin 或 net/http 中:
func sendEmailHandler(w http.ResponseWriter, r *http.Request) {
var data emailData
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest)
return
}
// 后续处理:data.To 是 []string,可遍历发送
log.Printf("To recipients: %v", data.To)
}
✅ 总结:面对无键 JSON 字符串数组,唯一且标准的 Go 映射方式是 []string —— 简洁、高效、零配置。避免类型猜测,坚持“JSON 数组 ↔ Go 切片”这一核心映射原则,即可彻底解决此类反序列化问题。











