
本文介绍如何正确使用 Go 的 json.Marshal 将两个平行字符串与整数数组(如 words 和 freq)组合成结构化的 JSON 字节切片,关键在于结构体字段导出、JSON 标签定义及整体切片序列化。
本文介绍如何正确使用 go 的 `json.marshal` 将两个平行字符串与整数数组(如 words 和 freq)组合成结构化的 json 字节切片,关键在于结构体字段导出、json 标签定义及整体切片序列化。
在 Go 中,要将 words 和 freq 两个平行数组转换为形如 [{"w":"apple","c":2},{"w":"banana","c":3},{"w":"peach","c":1}] 的 JSON 字节切片,需注意三个核心要点:结构体字段必须导出(首字母大写)、通过 JSON tag 自定义字段名、避免手动拼接字节切片(否则会丢失 JSON 数组语法结构)。
首先,定义可导出的结构体,并使用 json tag 映射为小写键名:
type Entry struct {
W string `json:"w"`
C int `json:"c"`
}
⚠️ 注意:若使用 w string(小写),该字段为非导出字段,json.Marshal 会忽略它,导致序列化结果为空对象 {} 或零值。
接着,构建 []Entry 切片并一次性 Marshal —— 这是正确且高效的方式:
func wordsFreqToJSON(words []string, freq []int) ([]byte, error) {
if len(words) != len(freq) {
return nil, fmt.Errorf("words and freq lengths mismatch")
}
entries := make([]Entry, len(words))
for i := range words {
entries[i] = Entry{
W: words[i],
C: freq[i],
}
}
return json.Marshal(entries)
}
调用示例:
words := []string{"apple", "banana", "peach"}
freq := []int{2, 3, 1}
data, err := wordsFreqToJSON(words, freq)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data)) // 输出: [{"w":"apple","c":2},{"w":"banana","c":3},{"w":"peach","c":1}]
❌ 原代码中 res := make([]byte, len(words)) 后直接 append(res, b...) 是错误的:它把多个独立 JSON 对象(如 {"w":"a","c":1}、{"w":"b","c":2})简单拼接为 {}{},而非合法的 JSON 数组。JSON 要求外层必须是 [...] 包裹的数组结构,而 json.Marshal([]Entry{...}) 会自动处理这一语法。
✅ 最佳实践总结:
- 始终使用导出字段(大写首字母)+
json:"key"tag 控制序列化键名; - 优先 Marshal 整个结构化切片,而非逐个 Marshal 后手动拼接;
- 添加长度校验,避免索引越界 panic;
- 错误处理不可省略,尤其在生产环境中需明确失败原因。
这样即可安全、清晰、符合 Go 惯例地生成目标格式的 JSON 字节数据。











