Format and remove 07.2.md spaces

This commit is contained in:
vCaesar
2017-06-10 11:58:54 +08:00
parent 0559b2f448
commit f250d5b806

View File

@@ -4,7 +4,7 @@ JSONJavascript Object Notation是一种轻量级的数据交换语言
前一小节的运维的例子用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
@@ -13,33 +13,33 @@ JSONJavascript Object Notation是一种轻量级的数据交换语言
假如有了上面的JSON串那么我们如何来解析这个JSON串呢Go的JSON包中有如下函数
```Go
func Unmarshal(data []byte, v interface{}) error
func Unmarshal(data []byte, v interface{}) error
```
通过这个函数我们就可以实现解析的目的,详细的解析例子请看如下代码:
```Go
package main
package main
import (
"encoding/json"
"fmt"
)
import (
"encoding/json"
"fmt"
)
type Server struct {
ServerName string
ServerIP string
}
type Server struct {
ServerName string
ServerIP string
}
type Serverslice struct {
Servers []Server
}
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)
}
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)
}
```
在上面的示例代码中我们首先定义了与json数据对应的结构体数组对应slice字段名对应JSON里面的KEY在解析的时候如何将json数据与struct字段相匹配呢例如JSON的key是`Foo`,那么怎么找对应的字段呢?
@@ -62,71 +62,71 @@ JSONJavascript Object Notation是一种轻量级的数据交换语言
现在我们假设有如下的JSON数据
```Go
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
```
如果在我们不知道他的结构的情况下我们把他解析到interface{}里面
```Go
var f interface{}
err := json.Unmarshal(b, &f)
var f interface{}
err := json.Unmarshal(b, &f)
```
这个时候f里面存储了一个map类型他们的key是string值存储在空的interface{}里
```Go
f = map[string]interface{}{
"Name": "Wednesday",
"Age": 6,
"Parents": []interface{}{
"Gomez",
"Morticia",
},
}
f = map[string]interface{}{
"Name": "Wednesday",
"Age": 6,
"Parents": []interface{}{
"Gomez",
"Morticia",
},
}
```
那么如何来访问这些数据呢?通过断言的方式:
```Go
m := f.(map[string]interface{})
m := f.(map[string]interface{})
```
通过断言之后,你就可以通过如下方式来访问里面的数据了
```Go
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")
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时相当方便详细例子如下所示
```Go
js, err := NewJson([]byte(`{
"test": {
"array": [1, "2", 3],
"int": 10,
"float": 5.150,
"bignum": 9223372036854775807,
"string": "simplejson",
"bool": true
}
}`))
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()
arr, _ := js.Get("test").Get("array").Array()
i, _ := js.Get("test").Get("int").Int()
ms := js.Get("test").Get("string").MustString()
```
可以看到使用这个库操作JSON比起官方包来说简单的多,详细的请参考如下地址https://github.com/bitly/go-simplejson
@@ -135,55 +135,55 @@ JSONJavascript Object Notation是一种轻量级的数据交换语言
我们开发很多应用的时候最后都是要输出JSON数据串那么如何来处理呢JSON包里面通过`Marshal`函数来处理,函数定义如下:
```Go
func Marshal(v interface{}) ([]byte, error)
func Marshal(v interface{}) ([]byte, error)
```
假设我们还是需要生成上面的服务器列表信息,那么如何来处理呢?请看下面的例子:
```Go
package main
package main
import (
"encoding/json"
"fmt"
)
import (
"encoding/json"
"fmt"
)
type Server struct {
ServerName string
ServerIP string
}
type Serverslice struct {
Servers []Server
}
func main() {
var s Serverslice
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"})
b, err := json.Marshal(s)
if err != nil {
fmt.Println("json err:", err)
}
fmt.Println(string(b))
type Server struct {
ServerName string
ServerIP string
}
type Serverslice struct {
Servers []Server
}
func main() {
var s Serverslice
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"})
b, err := json.Marshal(s)
if err != nil {
fmt.Println("json err:", err)
}
fmt.Println(string(b))
}
```
输出如下内容:
```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定义来实现
```Go
type Server struct {
ServerName string `json:"serverName"`
ServerIP string `json:"serverIP"`
}
type Server struct {
ServerName string `json:"serverName"`
ServerIP string `json:"serverIP"`
}
type Serverslice struct {
Servers []Server `json:"servers"`
}
type Serverslice struct {
Servers []Server `json:"servers"`
}
```
通过修改上面的结构体定义输出的JSON串就和我们最开始定义的JSON串保持一致了。
@@ -198,32 +198,32 @@ JSONJavascript Object Notation是一种轻量级的数据交换语言
举例来说:
```Go
type Server struct {
// ID 不会导出到JSON中
ID int `json:"-"`
type Server struct {
// ID 不会导出到JSON中
ID int `json:"-"`
// ServerName2 的值会进行二次JSON编码
ServerName string `json:"serverName"`
ServerName2 string `json:"serverName2,string"`
// ServerName2 的值会进行二次JSON编码
ServerName string `json:"serverName"`
ServerName2 string `json:"serverName2,string"`
// 如果 ServerIP 为空则不输出到JSON串中
ServerIP string `json:"serverIP,omitempty"`
}
// 如果 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)
s := Server {
ID: 3,
ServerName: `Go "1.0" `,
ServerName2: `Go "1.0" `,
ServerIP: ``,
}
b, _ := json.Marshal(s)
os.Stdout.Write(b)
```
会输出以下内容:
```json
{"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
{"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
```
Marshal函数只有在转换成功的时候才会返回数据在转换的过程中我们需要注意几点