解析显式数组

nor*_*wat 2 arrays json http go slice

我正在尝试从服务器解析这种类型的响应:

[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]
Run Code Online (Sandbox Code Playgroud)

除了为这种类型的消息编写我自己的hack'ish解析器之外,还有一种标准的解释方法,我不知道吗?

icz*_*cza 5

您的输入是JSON字符串.在Go中,您可以使用该encoding/json包对其进行解码.

通常,当JSON字符串的结构先前已知时,struct可以构造一个对其进行建模的Go 类型,然后您可以解组为该struct类型的值.

如果结构未知或变化,您可以解组为类型的值,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)
Run Code Online (Sandbox Code Playgroud)

输出(在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}}}}
Run Code Online (Sandbox Code Playgroud)

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

这是添加缩进的相同输出以获得更好的感觉(使用Go的复合文字语法):

[]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},
        },
    },
}
Run Code Online (Sandbox Code Playgroud)

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

fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[0])
fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[1])
Run Code Online (Sandbox Code Playgroud)

输出:

float64 1
string a
Run Code Online (Sandbox Code Playgroud)

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