解析显式数组

Parsing explicit arrays

我正在尝试解析来自服务器的此类响应:

[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]

除了为此类消息编写我自己的 hack'ish 解析器之外,是否有一种我不知道的标准方法来解释它?

你的输入是一个JSON string. In Go, you can use the encoding/json包来解码它。

通常,当 JSON 字符串的结构事先已知时,可以构造一个对其建模的 Go struct 类型,然后您可以解组为该 [=16] 的值=]类型。

如果结构未知或发生变化,您可以解组为 interface{} 类型的值,它可以是任何 JSON 数据的目标:

s := `[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]`

var v interface{}
if err := json.Unmarshal([]byte(s), &v); err != nil {
    fmt.Println(err)
    return
}
fmt.Println(v)
fmt.Printf("%#v\n", v)

输出(在 Go Playground 上尝试):

[[1 a b 2 000000 [[1 2 3] [1 2 3]] x y z [[1 2 3] [1 2 3]]]]
[]interface {}{[]interface {}{1, "a", "b", 2, "000000", []interface {}{[]interface {}{1, 2, 3}, []interface {}{1, 2, 3}}, "x", "y", "z", []interface {}{[]interface {}{1, 2, 3}, []interface {}{1, 2, 3}}}}

如您所见,结果是一个切片的切片,具有不同类型的元素(JSON 数字、字符串甚至更多切片)。

这是相同的输出,添加缩进以获得更好的感觉(使用 Go 的 composite literal 语法):

[]interface{}{
    []interface{}{
        1, "a", "b", 2, "000000",
        []interface{}{
            []interface{}{1, 2, 3},
            []interface{}{1, 2, 3}},
        "x", "y", "z",
        []interface{}{
            []interface{}{1, 2, 3},
            []interface{}{1, 2, 3},
        },
    },
}

当然这不是很方便,因为你必须使用 type assertion 到 "extract" 类型的 "generic" 值 interface{} 的值,例如提取前 2 个非数组值(也打印它们的类型以进行验证):

fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[0])
fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[1])

输出:

float64 1
string a

值得注意的是,Go 中的 JSON 数字被解组为 float64 类型的值,即使它们可能是整数(除非明确指定另一种类型)。