Format and remove 07.2.md spaces
This commit is contained in:
220
zh/07.2.md
220
zh/07.2.md
@@ -4,7 +4,7 @@ JSON(Javascript Object Notation)是一种轻量级的数据交换语言,
|
|||||||
前一小节的运维的例子用json来表示,结果描述如下:
|
前一小节的运维的例子用json来表示,结果描述如下:
|
||||||
```json
|
```json
|
||||||
|
|
||||||
{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}
|
{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}
|
||||||
```
|
```
|
||||||
本小节余下的内容将以此JSON数据为基础,来介绍go语言的json包对JSON数据的编、解码。
|
本小节余下的内容将以此JSON数据为基础,来介绍go语言的json包对JSON数据的编、解码。
|
||||||
## 解析JSON
|
## 解析JSON
|
||||||
@@ -13,33 +13,33 @@ JSON(Javascript Object Notation)是一种轻量级的数据交换语言,
|
|||||||
假如有了上面的JSON串,那么我们如何来解析这个JSON串呢?Go的JSON包中有如下函数
|
假如有了上面的JSON串,那么我们如何来解析这个JSON串呢?Go的JSON包中有如下函数
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
func Unmarshal(data []byte, v interface{}) error
|
func Unmarshal(data []byte, v interface{}) error
|
||||||
```
|
```
|
||||||
通过这个函数我们就可以实现解析的目的,详细的解析例子请看如下代码:
|
通过这个函数我们就可以实现解析的目的,详细的解析例子请看如下代码:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
ServerName string
|
ServerName string
|
||||||
ServerIP string
|
ServerIP string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Serverslice struct {
|
type Serverslice struct {
|
||||||
Servers []Server
|
Servers []Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var s Serverslice
|
var s Serverslice
|
||||||
str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}`
|
str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}`
|
||||||
json.Unmarshal([]byte(str), &s)
|
json.Unmarshal([]byte(str), &s)
|
||||||
fmt.Println(s)
|
fmt.Println(s)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
在上面的示例代码中,我们首先定义了与json数据对应的结构体,数组对应slice,字段名对应JSON里面的KEY,在解析的时候,如何将json数据与struct字段相匹配呢?例如JSON的key是`Foo`,那么怎么找对应的字段呢?
|
在上面的示例代码中,我们首先定义了与json数据对应的结构体,数组对应slice,字段名对应JSON里面的KEY,在解析的时候,如何将json数据与struct字段相匹配呢?例如JSON的key是`Foo`,那么怎么找对应的字段呢?
|
||||||
|
|
||||||
@@ -62,71 +62,71 @@ JSON(Javascript Object Notation)是一种轻量级的数据交换语言,
|
|||||||
现在我们假设有如下的JSON数据
|
现在我们假设有如下的JSON数据
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
|
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
|
||||||
```
|
```
|
||||||
如果在我们不知道他的结构的情况下,我们把他解析到interface{}里面
|
如果在我们不知道他的结构的情况下,我们把他解析到interface{}里面
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
var f interface{}
|
var f interface{}
|
||||||
err := json.Unmarshal(b, &f)
|
err := json.Unmarshal(b, &f)
|
||||||
```
|
```
|
||||||
这个时候f里面存储了一个map类型,他们的key是string,值存储在空的interface{}里
|
这个时候f里面存储了一个map类型,他们的key是string,值存储在空的interface{}里
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
f = map[string]interface{}{
|
f = map[string]interface{}{
|
||||||
"Name": "Wednesday",
|
"Name": "Wednesday",
|
||||||
"Age": 6,
|
"Age": 6,
|
||||||
"Parents": []interface{}{
|
"Parents": []interface{}{
|
||||||
"Gomez",
|
"Gomez",
|
||||||
"Morticia",
|
"Morticia",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
那么如何来访问这些数据呢?通过断言的方式:
|
那么如何来访问这些数据呢?通过断言的方式:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
m := f.(map[string]interface{})
|
m := f.(map[string]interface{})
|
||||||
```
|
```
|
||||||
通过断言之后,你就可以通过如下方式来访问里面的数据了
|
通过断言之后,你就可以通过如下方式来访问里面的数据了
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
switch vv := v.(type) {
|
switch vv := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
fmt.Println(k, "is string", vv)
|
fmt.Println(k, "is string", vv)
|
||||||
case int:
|
case int:
|
||||||
fmt.Println(k, "is int", vv)
|
fmt.Println(k, "is int", vv)
|
||||||
case float64:
|
case float64:
|
||||||
fmt.Println(k,"is float64",vv)
|
fmt.Println(k,"is float64",vv)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
fmt.Println(k, "is an array:")
|
fmt.Println(k, "is an array:")
|
||||||
for i, u := range vv {
|
for i, u := range vv {
|
||||||
fmt.Println(i, u)
|
fmt.Println(i, u)
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Println(k, "is of a type I don't know how to handle")
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
fmt.Println(k, "is of a type I don't know how to handle")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
通过上面的示例可以看到,通过interface{}与type assert的配合,我们就可以解析未知结构的JSON数了。
|
通过上面的示例可以看到,通过interface{}与type assert的配合,我们就可以解析未知结构的JSON数了。
|
||||||
|
|
||||||
上面这个是官方提供的解决方案,其实很多时候我们通过类型断言,操作起来不是很方便,目前bitly公司开源了一个叫做`simplejson`的包,在处理未知结构体的JSON时相当方便,详细例子如下所示:
|
上面这个是官方提供的解决方案,其实很多时候我们通过类型断言,操作起来不是很方便,目前bitly公司开源了一个叫做`simplejson`的包,在处理未知结构体的JSON时相当方便,详细例子如下所示:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
js, err := NewJson([]byte(`{
|
js, err := NewJson([]byte(`{
|
||||||
"test": {
|
"test": {
|
||||||
"array": [1, "2", 3],
|
"array": [1, "2", 3],
|
||||||
"int": 10,
|
"int": 10,
|
||||||
"float": 5.150,
|
"float": 5.150,
|
||||||
"bignum": 9223372036854775807,
|
"bignum": 9223372036854775807,
|
||||||
"string": "simplejson",
|
"string": "simplejson",
|
||||||
"bool": true
|
"bool": true
|
||||||
}
|
}
|
||||||
}`))
|
}`))
|
||||||
|
|
||||||
arr, _ := js.Get("test").Get("array").Array()
|
arr, _ := js.Get("test").Get("array").Array()
|
||||||
i, _ := js.Get("test").Get("int").Int()
|
i, _ := js.Get("test").Get("int").Int()
|
||||||
ms := js.Get("test").Get("string").MustString()
|
ms := js.Get("test").Get("string").MustString()
|
||||||
|
|
||||||
```
|
```
|
||||||
可以看到,使用这个库操作JSON比起官方包来说,简单的多,详细的请参考如下地址:https://github.com/bitly/go-simplejson
|
可以看到,使用这个库操作JSON比起官方包来说,简单的多,详细的请参考如下地址:https://github.com/bitly/go-simplejson
|
||||||
@@ -135,55 +135,55 @@ JSON(Javascript Object Notation)是一种轻量级的数据交换语言,
|
|||||||
我们开发很多应用的时候,最后都是要输出JSON数据串,那么如何来处理呢?JSON包里面通过`Marshal`函数来处理,函数定义如下:
|
我们开发很多应用的时候,最后都是要输出JSON数据串,那么如何来处理呢?JSON包里面通过`Marshal`函数来处理,函数定义如下:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
func Marshal(v interface{}) ([]byte, error)
|
func Marshal(v interface{}) ([]byte, error)
|
||||||
```
|
```
|
||||||
假设我们还是需要生成上面的服务器列表信息,那么如何来处理呢?请看下面的例子:
|
假设我们还是需要生成上面的服务器列表信息,那么如何来处理呢?请看下面的例子:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
ServerName string
|
ServerName string
|
||||||
ServerIP string
|
ServerIP string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Serverslice struct {
|
type Serverslice struct {
|
||||||
Servers []Server
|
Servers []Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var s Serverslice
|
var s Serverslice
|
||||||
s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"})
|
s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"})
|
||||||
s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"})
|
s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"})
|
||||||
b, err := json.Marshal(s)
|
b, err := json.Marshal(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("json err:", err)
|
fmt.Println("json err:", err)
|
||||||
}
|
|
||||||
fmt.Println(string(b))
|
|
||||||
}
|
}
|
||||||
|
fmt.Println(string(b))
|
||||||
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
输出如下内容:
|
输出如下内容:
|
||||||
```json
|
```json
|
||||||
|
|
||||||
{"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}]}
|
{"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}]}
|
||||||
```
|
```
|
||||||
我们看到上面的输出字段名的首字母都是大写的,如果你想用小写的首字母怎么办呢?把结构体的字段名改成首字母小写的?JSON输出的时候必须注意,只有导出的字段才会被输出,如果修改字段名,那么就会发现什么都不会输出,所以必须通过struct tag定义来实现:
|
我们看到上面的输出字段名的首字母都是大写的,如果你想用小写的首字母怎么办呢?把结构体的字段名改成首字母小写的?JSON输出的时候必须注意,只有导出的字段才会被输出,如果修改字段名,那么就会发现什么都不会输出,所以必须通过struct tag定义来实现:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
ServerName string `json:"serverName"`
|
ServerName string `json:"serverName"`
|
||||||
ServerIP string `json:"serverIP"`
|
ServerIP string `json:"serverIP"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Serverslice struct {
|
type Serverslice struct {
|
||||||
Servers []Server `json:"servers"`
|
Servers []Server `json:"servers"`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
通过修改上面的结构体定义,输出的JSON串就和我们最开始定义的JSON串保持一致了。
|
通过修改上面的结构体定义,输出的JSON串就和我们最开始定义的JSON串保持一致了。
|
||||||
|
|
||||||
@@ -198,32 +198,32 @@ JSON(Javascript Object Notation)是一种轻量级的数据交换语言,
|
|||||||
举例来说:
|
举例来说:
|
||||||
```Go
|
```Go
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// ID 不会导出到JSON中
|
// ID 不会导出到JSON中
|
||||||
ID int `json:"-"`
|
ID int `json:"-"`
|
||||||
|
|
||||||
// ServerName2 的值会进行二次JSON编码
|
// ServerName2 的值会进行二次JSON编码
|
||||||
ServerName string `json:"serverName"`
|
ServerName string `json:"serverName"`
|
||||||
ServerName2 string `json:"serverName2,string"`
|
ServerName2 string `json:"serverName2,string"`
|
||||||
|
|
||||||
// 如果 ServerIP 为空,则不输出到JSON串中
|
// 如果 ServerIP 为空,则不输出到JSON串中
|
||||||
ServerIP string `json:"serverIP,omitempty"`
|
ServerIP string `json:"serverIP,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
s := Server {
|
s := Server {
|
||||||
ID: 3,
|
ID: 3,
|
||||||
ServerName: `Go "1.0" `,
|
ServerName: `Go "1.0" `,
|
||||||
ServerName2: `Go "1.0" `,
|
ServerName2: `Go "1.0" `,
|
||||||
ServerIP: ``,
|
ServerIP: ``,
|
||||||
}
|
}
|
||||||
b, _ := json.Marshal(s)
|
b, _ := json.Marshal(s)
|
||||||
os.Stdout.Write(b)
|
os.Stdout.Write(b)
|
||||||
|
|
||||||
```
|
```
|
||||||
会输出以下内容:
|
会输出以下内容:
|
||||||
```json
|
```json
|
||||||
|
|
||||||
{"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
|
{"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
|
||||||
|
|
||||||
```
|
```
|
||||||
Marshal函数只有在转换成功的时候才会返回数据,在转换的过程中我们需要注意几点:
|
Marshal函数只有在转换成功的时候才会返回数据,在转换的过程中我们需要注意几点:
|
||||||
|
|||||||
Reference in New Issue
Block a user