- Json
1 解析到结构体
package main import ( "encoding/json" "fmt" ) type Server struct { ServerName string ServerIP string } type Serverslice struct { Servers []Server } func main() { var s Serverslice str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}` json.Unmarshal([]byte(str), &s) fmt.Println(s) }
2 解析到Interface{}
上面那种解析方式是在我们知晓被解析的JSON数据的结构的前提下采取的方案,如果我们不知道被解析的数据的格式,又应该如何来解析呢?
我们知道interface{}可以用来存储任意数据类型的对象,这种数据结构正好用于存储解析的未知结构的json数据的结果。JSON包中采用map[string]interface{}和[]interface{}结构来存储任意的JSON对象和数组。Go类型和JSON类型的对应关系如下:
- bool 代表 JSON booleans,
- float64 代表 JSON numbers,
- string 代表 JSON strings,
- nil 代表 JSON null.
现在我们假设有如下的JSON数据
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
如果在我们不知道他的结构的情况下,我们把他解析到interface{}里面
var f interface{}
err := json.Unmarshal(b, &f)
这个时候f里面存储了一个map类型,他们的key是string,值存储在空的interface{}里
f = map[string]interface{}{
"Name": "Wednesday",
"Age": 6,
"Parents": []interface{}{
"Gomez",
"Morticia",
},
}
那么如何来访问这些数据呢?通过断言的方式:
m := f.(map[string]interface{})
通过断言之后,你就可以通过如下方式来访问里面的数据了
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case float64:
fmt.Println(k,"is float64",vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
通过上面的示例可以看到,通过interface{}与type assert的配合,我们就可以解析未知结构的JSON数了。
上面这个是官方提供的解决方案,其实很多时候我们通过类型断言,操作起来不是很方便,目前bitly公司开源了一个叫做simplejson
的包,在处理未知结构体的JSON时相当方便,详细例子如下所示:
js, err := NewJson([]byte(`{
"test": {
"array": [1, "2", 3],
"int": 10,
"float": 5.150,
"bignum": 9223372036854775807,
"string": "simplejson",
"bool": true
}
}`))
arr, _ := js.Get("test").Get("array").Array()
i, _ := js.Get("test").Get("int").Int()
ms := js.Get("test").Get("string").MustString()
3 生成json
type Server struct { // ID 不会导出到JSON中 ID int `json:"-"` // ServerName2 的值会进行二次JSON编码 ServerName string `json:"serverName"` ServerName2 string `json:"serverName2,string"` // 如果 ServerIP 为空,则不输出到JSON串中 ServerIP string `json:"serverIP,omitempty"` } s := Server { ID: 3, ServerName: `Go "1.0" `, ServerName2: `Go "1.0" `, ServerIP: ``, } b, _ := json.Marshal(s) os.Stdout.Write(b)