
Go 语言中可通过将结构体字段声明为 []string 类型,直接解码 JSON 中的字符串数组(如 "to" 和 "cc"),无需预知长度或额外转换。
go 语言中可通过将结构体字段声明为 `[]string` 类型,直接解码 json 中的字符串数组(如 `"to"` 和 `"cc"`),无需预知长度或额外转换。
在 Go 的 JSON 解析中,JSON 数组(如 ["a@example.com", "b@example.com"])天然对应 Go 的切片类型(如 []string),而非 map 或单个字符串。原结构体中将 To 声明为 map[string]string、CC 声明为 string,会导致 json.Unmarshal 解析失败(返回 json.UnmarshalTypeError),因为类型不匹配。
✅ 正确做法是:将数组字段统一映射为 []string 类型,并确保 JSON tag 名称严格匹配(注意大小写,如 "to" 小写,非 "To"):
type emailData struct {
Body struct {
Template string `json:"template"`
Params map[string]string `json:"params"`
} `json:"body"`
To []string `json:"to"` // ✅ 匹配 JSON 中的 "to": ["...", "..."]
CC []string `json:"cc"` // ✅ 匹配 "cc": ["...", "..."]
ReplyTo struct {
Email string `json:"email"`
Name string `json:"name"`
} `json:"replyTo"` // ✅ 注意 tag 中的大小写与 JSON key 一致
BCC string `json:"bcc"`
Subject string `json:"subject"`
}
⚠️ 关键注意事项:
- JSON key 是区分大小写的(
"to"≠"To"),结构体 tag 必须完全一致; -
ReplyTo字段缺少json:"replyTo"tag,若不加则默认使用字段名ReplyTo(首字母大写),导致解析失败; -
BCC和Subject字段虽为单值,但需确认 JSON 中确实为字符串(本例中"bcc"是字符串,符合); - 若某些字段可能为空(如
"cc": null),可使用指针(*[]string)或自定义UnmarshalJSON方法增强容错性。
完整示例(含解析验证):
func main() {
jsonData := `{
"body": {"template": "abctemplate.html", "params": {"name":"Chase"}},
"to": ["alice@example.com", "bob@example.com"],
"cc": ["carol@example.com"],
"replyTo": {"email": "jack@example.com", "name": "Jack"},
"bcc": "admin@example.com",
"subject": "Hello, world!"
}`
var data emailData
if err := json.Unmarshal([]byte(jsonData), &data); err != nil {
log.Fatal("Parse error:", err)
}
fmt.Printf("To: %v\n", data.To) // [alice@example.com bob@example.com]
fmt.Printf("CC: %v\n", data.CC) // [carol@example.com]
fmt.Printf("ReplyTo.Email: %s\n", data.ReplyTo.Email) // jack@example.com
}
总结:处理无键 JSON 数组的核心原则是——用 Go 切片([]T)对齐 JSON 数组,用精确的 json:"key" tag 对齐字段名。无需手动遍历或中间转换,encoding/json 包原生支持该映射。











