decoder.more 总是返回 false 是因为它仅适用于多个独立 json 值(如 ndjson)的流式解析,而非标准 json 数组;对 [{"id":1},{"id":2}] 这类数组,整个输入被视为单个值,解析完即无后续,故 more() 返回 false;正确做法是用 token() 手动遍历或 unmarshal 整体解析。

Decoder.More 为什么总是返回 false?
因为 Decoder.More 不是为“遍历 JSON 数组”设计的——它只在解码流式 JSON(如多个顶级 JSON 值连续写入)时才有意义。如果你把一个标准 JSON 数组([{"id":1},{"id":2}])喂给 json.NewDecoder,调用 More() 会立刻返回 false,因为整个输入被当作单个 JSON 值(数组)解析完毕,没有“下一个值”可读。
想逐个解码数组元素,该用什么?
直接跳过 More(),改用以下任一方式:
- 先用
json.Unmarshal解析整个数组到切片(适合小数组、内存充足) - 用
Decoder.Token()手动推进:读到[后,循环读{→ 解码结构体 → 直到遇到] - 对大数组或流式场景,用
jsoniter或go-json的迭代器模式(它们提供原生数组元素迭代)
标准库最简可行方案示例:
d := json.NewDecoder(strings.NewReader(`[{"id":1},{"id":2},{"id":3}]`))
tok, _ := d.Token() // 读 "["
for {
tok, _ := d.Token()
if tok == json.Delim(']') {
break
}
if tok == json.Delim('{') {
var item struct{ ID int }
d.Decode(&item) // 此时 d 已定位在 { 内部
fmt.Println(item.ID)
}
}
Decoder.More 的真实使用场景
它只在输入包含多个独立 JSON 值时有效,比如一行一个 JSON 对象(NDJSON):
{"id":1}
{"id":2}
{"id":3}
这时要这样用:
- 每次
Decode()一个对象后,检查More()是否为true,决定是否继续 - 必须确保输入是多个顶层 JSON 值,不能是数组包裹的值
- 常见于 HTTP 流响应、日志行、WebSocket 消息流
错误示范:Decoder.More() 对 [1,2,3] 或 [{"a":1}] 无意义,别硬套。
容易忽略的边界问题
手动 Token 遍历时,Decoder.Decode() 会自动跳过空白和分隔符,但 Token() 不会——你得自己处理逗号、换行、嵌套结构。尤其注意:
- 数组内对象之间可能有逗号,也可能没有(最后一个元素后无逗号),
Token()会把逗号作为json.Comma返回,需显式跳过 - 如果数组里混了不同结构(如
[{"x":1}, "str", 42]),Decode()会 panic,得用RawMessage兜底 -
More()在 EOF 或语法错误时行为不一致:EOF 返回false,但某些错误可能 panic 而非返回false
真要稳健处理 JSON 数组流,别指望 More(),老老实实走 Token 循环或换专用库。











