Remove 07.2.md spaces

This commit is contained in:
vCaesar
2017-06-09 21:59:35 +08:00
parent 3cde33294b
commit d96a99079d

View File

@@ -8,7 +8,7 @@ Since JSON is becoming more and more important in web development, let's take a
Here we use JSON to represent the example in the previous section: Here we use JSON to represent the example in the previous section:
```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"}]}
``` ```
The rest of this section will use this JSON data to introduce JSON concepts in Go. The rest of this section will use this JSON data to introduce JSON concepts in Go.
@@ -18,33 +18,33 @@ The rest of this section will use this JSON data to introduce JSON concepts in G
Suppose we have the JSON in the above example. How can we parse this data and map it to a struct in Go? Go provides the following function for just this purpose: Suppose we have the JSON in the above example. How can we parse this data and map it to a struct in Go? Go provides the following function for just this purpose:
```Go ```Go
func Unmarshal(data []byte, v interface{}) error func Unmarshal(data []byte, v interface{}) error
``` ```
We can use this function like so: We can use this function like so:
```Go ```Go
package main package main
import (
"encoding/json"
"fmt"
)
type Server struct {
ServerName string
ServerIP string
}
type Serverslice struct {
Servers []Server
}
func main() { import (
var s Serverslice "encoding/json"
str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}` "fmt"
json.Unmarshal([]byte(str), &s) )
fmt.Println(s)
} 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)
}
``` ```
In the above example, we defined a corresponding structs in Go for our JSON, using slice for an array of JSON objects and field name as our JSON keys. But how does Go know which JSON object corresponds to which specific struct filed? Suppose we have a key called `Foo` in JSON. How do we find its corresponding field? In the above example, we defined a corresponding structs in Go for our JSON, using slice for an array of JSON objects and field name as our JSON keys. But how does Go know which JSON object corresponds to which specific struct filed? Suppose we have a key called `Foo` in JSON. How do we find its corresponding field?
@@ -67,66 +67,66 @@ We know that an interface{} can be anything in Go, so it is the best container t
Suppose we have the following JSON data: Suppose we have the following JSON data:
```Go ```Go
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`) b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
``` ```
Now we parse this JSON to an interface{}: Now we parse this JSON to an interface{}:
```Go ```Go
var f interface{} var f interface{}
err := json.Unmarshal(b, &f) err := json.Unmarshal(b, &f)
``` ```
The `f` stores a map, where keys are strings and values are interface{}'s'. The `f` stores a map, where keys are strings and values are interface{}'s'.
```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",
}, },
} }
``` ```
So, how do we access this data? Type assertion. So, how do we access this data? Type assertion.
```Go ```Go
m := f.(map[string]interface{}) m := f.(map[string]interface{})
``` ```
After asserted, you can use the following code to access data: After asserted, you can use the following code to access data:
```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: default:
fmt.Println(k, "is of a type I don't know how to handle") fmt.Println(k, "is of a type I don't know how to handle")
} }
} }
``` ```
As you can see, we can now parse JSON of an unknown format through interface{} and type assertion. As you can see, we can now parse JSON of an unknown format through interface{} and type assertion.
The above example is the official solution, but type asserting is not always convenient. So, I recommend an open source project called `simplejson`, created and maintained by bitly. Here is an example of how to use this project to deal with JSON of an unknown format: The above example is the official solution, but type asserting is not always convenient. So, I recommend an open source project called `simplejson`, created and maintained by bitly. Here is an example of how to use this project to deal with JSON of an unknown format:
```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()
``` ```
It's not hard to see how convenient this is. Check out the repository to see more information: [https://github.com/bitly/go-simplejson](https://github.com/bitly/go-simplejson). It's not hard to see how convenient this is. Check out the repository to see more information: [https://github.com/bitly/go-simplejson](https://github.com/bitly/go-simplejson).
@@ -134,51 +134,51 @@ It's not hard to see how convenient this is. Check out the repository to see mor
In many situations, we need to produce JSON data and respond to clients. In Go, the JSON package has a function called `Marshal` to do just that: In many situations, we need to produce JSON data and respond to clients. In Go, the JSON package has a function called `Marshal` to do just that:
```Go ```Go
func Marshal(v interface{}) ([]byte, error) func Marshal(v interface{}) ([]byte, error)
``` ```
Suppose we need to produce a server information list. We have following sample: Suppose we need to produce a server information list. We have following sample:
```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))
} }
``` ```
Output: Output:
```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"}]}
``` ```
As you know, all field names are capitalized, but if you want your JSON key names to start with a lower case letter, you should use `struct tag`s. Otherwise, Go will not produce data for internal fields. As you know, all field names are capitalized, but if you want your JSON key names to start with a lower case letter, you should use `struct tag`s. Otherwise, Go will not produce data for internal fields.
```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"`
} }
``` ```
After this modification, we can produce the same JSON data as before. After this modification, we can produce the same JSON data as before.
@@ -191,30 +191,30 @@ Here are some points you need to keep in mind when trying to produce JSON:
Example: Example:
```Go ```Go
type Server struct { type Server struct {
// ID will not be outputed. // ID will not be outputed.
ID int `json:"-"` ID int `json:"-"`
// ServerName2 will be converted to JSON type. // ServerName2 will be converted to JSON type.
ServerName string `json:"serverName"` ServerName string `json:"serverName"`
ServerName2 string `json:"serverName2,string"` ServerName2 string `json:"serverName2,string"`
// If ServerIP is empty, it will not be outputted. // If ServerIP is empty, it will not be outputted.
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)
``` ```
Output: Output:
```json ```json
{"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""} {"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
``` ```
The `Marshal` function only returns data when it has succeeded, so here are some points we need to keep in mind: The `Marshal` function only returns data when it has succeeded, so here are some points we need to keep in mind: