使用Go语言解析JSON数组和映射元素时出现运行时错误,原因是末尾逗号的问题。

8
Dave Cheney, Go的领先专家之一,写道:“当使用复合字面量初始化变量时,Go要求每行复合字面量都以逗号结尾,即使是声明的最后一行。这是semicolon rule的结果。”
然而,当我试图将这个美丽的规则应用于JSON文本时,解析器似乎不同意这种哲学。在下面的代码中,删除逗号是有效的。是否有办法修复这个问题,这样当我在差异中添加元素时,只能看到一行变化?
package main

import (
    "fmt"
    "encoding/json"
)

type jsonobject struct {
    Objects []ObjectType `json:"objects"`
}

type ObjectType struct {
    Name string `json:"name"`
}

func main() {
    bytes := []byte(`{ "objects": 
        [ 
            {"name": "foo"}, // REMOVE THE COMMA TO MAKE THE CODE WORK!
        ]}`)
    jsontype := &jsonobject{}
    json.Unmarshal(bytes, &jsontype)
    fmt.Printf("Results: %v\n", jsontype.Objects[0].Name) // panic: runtime error: index out of range
}
2个回答

6

没有。JSON规范不允许有尾随逗号。

这不是一个有效的JSON:

{ "objects": 
    [ 
        {"name": "foo"},
]}

如果枚举没有在同一行关闭,那么你需要使用逗号作为Go语法(更多信息),例如:

// Slice literal:
s := []int {
    1,
    2,
}

// Function call:
fmt.Println(
    "Slice:",
    s,
)

即使您可以“说服”一个特定的JSON解析器默默地吞下它,其他有效的JSON解析器也会报告错误,这是正确的。不要这样做。

3
尽管尾随逗号在JSON中是无效的,但某些语言本地支持尾随逗号,特别是JavaScript,因此您可能会在数据中看到它们。
最好删除尾随逗号,但如果您无法更改数据,请使用支持尾随逗号的JSON解析器,例如HuJSON(也称为Human JSON),它支持JSON中的尾随逗号和注释。该项目由著名的Xoogler和前Golang团队成员Brad Fitzpatrick等人维护 为了将数据Unmarshal为任意Go类型,请使用以下方法:
b, err := hujson.Standardize(inputBytes)
if err != nil {
    ... // handle err
}

v := map[string]any{}
if err := json.Unmarshal(b, &v); err != nil {
    ... // handle err
}

我用过它,它的效果和描述的一样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接