【问题标题】:Runtime error when parsing JSON array and map elements with trailing commas解析带有尾随逗号的 JSON 数组和映射元素时出现运行时错误
【发布时间】:2016-08-01 13:45:51
【问题描述】:

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
}

【问题讨论】:

    标签: json go gofmt


    【解决方案1】:

    没有。 JSON specification 不允许尾随逗号。

    这不是一个有效的 JSON:

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

    这是一种Go语法,如果枚举没有关闭就需要使用逗号(more on this),例如:

    // Slice literal:
    s := []int {
        1,
        2,
    }
    
    // Function call:
    fmt.Println(
        "Slice:",
        s,
    )
    

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

    【讨论】:

      【解决方案2】:

      虽然尾随逗号不是有效的 JSON,但某些语言本身就支持尾随逗号,尤其是 JavaScript,因此您可能会在数据中看到它们。

      最好删除尾随逗号,但如果您无法更改数据,请使用支持尾随逗号的 JSON 解析器,如 HuJSON(又名 Human JSON),它支持 JSON 中的尾随逗号和 cmets。这是著名的 Xoogler 和前 Golang 团队成员 Brad Fitzpatrick 和其他人对 encoding/jsonis maintained 的软分叉。

      Unmarshal 语法与encoding/json 相同,只需使用:

      err := hujson.Unmarshal(data, v)
      

      我用过它,它的工作原理和描述的一样。

      【讨论】:

        猜你喜欢
        • 2017-04-29
        • 1970-01-01
        • 2019-03-09
        • 2012-06-18
        • 1970-01-01
        • 2016-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多