解析显式数组

huangapple go评论108阅读模式
英文:

Parsing explicit arrays

问题

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

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

除了编写自己的解析器来处理这种类型的消息之外,是否有一种标准的方法来解释这个问题,我不知道吗?

英文:

I'm trying to parse this type of response from a server:

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

Besides writing my own hack'ish parser for this type of messages is there a standard way to interpret this that I'm not aware of?

答案1

得分: 7

你的输入是一个JSON字符串。在Go语言中,你可以使用encoding/json包来解码它。

通常情况下,当已知JSON字符串的结构时,可以构建一个对应该结构的Go struct类型,并将其解组为该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)

输出结果(在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的[复合字面量][4]语法):

```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},
        },
    },
}

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

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

值得注意的是,尽管JSON中的数字可以是整数(除非另外指定了其他类型),但在Go中,它们被解组为float64类型的值。

英文:

Your input is a JSON string. In Go, you can use the encoding/json package to decode it.

Usually, when the structure of the JSON string is known prior, a Go struct type can be constructed which models it, and then you can unmarshal into a value of that struct type.

If the structure is unknown or is varying, you may unmarshal into a value of type interface{} which can be the target of any JSON data:

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)

Output (try it on the 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}}}}

As you can see, the result is a slice of slices, with elements of varying types (JSON numbers, strings and even more slices).

Here's the same output adding indentation to get a better feeling of it (using Go's composite literal syntax):

[]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},
		},
	},
}

Of course this is not very convenient, as you have to use type assertion to "extract" values from this "generic" value of type interface{}, for example to extract the first 2 non-arrays values (also printing their types for verification):

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

Output:

float64 1
string a

Worth noting that JSON numbers in Go are unmarshaled to a value of type float64 even though they could be integers (unless another type is explicitly specified).

huangapple
  • 本文由 发表于 2016年10月31日 04:59:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/40333562.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定