Go语言 encoding/json包
Go语言自带的 JSON转换库

func Marshal(v interface{}) ([]byte, error)
把对象转换为JSON 布尔型转换为 JSON 后仍是布尔型 如 true -> true
浮点型 和 整数型转换后为 JSON里面的 常规数字 如 1.23 -> 1.23
字符串 将 以UTF-8编码转化输出为 Unicode字符集的字符串 特殊字符比如 <将会被转义为 \u003c
数组 和 切片被转换为JSON 里面的数组 []byte 类 会被转换为base64编码后的字符串 slice 的零值被转换为null
结构体 转化为 JSON对象 且 只有结构体里边以 大写字母开头 的可被导出的字段才会被转化输出 而这些可导出的字段会作为JSON对象的字符串索引
转化 map 类型的数据结构时 该数据的类型必须是 map[string]T(T 可以是 encoding/json 包支持的任意数据类型)


package main     
import (
    "encoding/json"
    "fmt"
    "os"
)
func main() {
    type ColorGroup struct {
        ID     int
        Name   string
        Colors []string
    }
    group := ColorGroup{
        ID:     1,
        Name:   "Reds",
        Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
    }
    b, err := json.Marshal(group)
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stdout.Write(b)
}//输出 {“ID”:1,”Name”:”Reds”,”Colors”:[“Crimson”,”Red”,”Ruby”,”Maroon”]}

func Unmarshal(data [] byte, v interface{}) error
把 JSON 转换回对象 把传入的 data 作为 JSON  解析 解析后的数据存 在参数 v 中
参数 v 是类型任意 (但一定是一个类型的指针)
原因是 在是以此函数进行JSON 解析的时候  函数不知道 传入参数的具体类型 所以 需要接收所有的类型
package main
import (
    "encoding/json"
    "fmt"
)
func main() {
    var jsonBlob = []byte(`[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]`)
    type Animal struct {
        Name  string
        Order string
    }
    var animals []Animal
    err := json.Unmarshal(jsonBlob, &animals)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Printf("%+v", animals)
}
输出 [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]

Encoders and Decoders
NewDecoder returns a new decoder that reads from r.

func NewDecoder(r io.Reader) *Decoder
A Decoder reads and decodes JSON values from an input stream.
type Decoder struct {
 // contains filtered or unexported fields
}

An Encoder writes JSON values to an output stream.
type Encoder struct {
 // contains filtered or unexported fields
}

package main     
import (
    "encoding/json"
    "fmt"
    "io"
    "log"
    "strings"
)
func main() {
    const jsonStream = `
        {"Name": "Ed", "Text": "Knock knock."}
        {"Name": "Sam", "Text": "Who's there?"}
        {"Name": "Ed", "Text": "Go fmt."}
        {"Name": "Sam", "Text": "Go fmt who?"}
        {"Name": "Ed", "Text": "Go fmt yourself!"}
    `
    type Message struct {
        Name, Text string
    }
    dec := json.NewDecoder(strings.NewReader(jsonStream))
    for {
        var m Message
        if err := dec.Decode(&m); err == io.EOF {
            break
        } else if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s: %s\n", m.Name, m.Text)
    }
}

Encode 和 Marshal 区别
func Encode is a method on an Encoder which writes JSON encoded Go types to an output stream (func NewEncoder takes an io.Writer and returns a *Encoder)
Marshal is a function that returns JSON encoding of Go types

package main
import (
"encoding/json"
"fmt"
"os"
)
// We'll use these two structs to demonstrate encoding and decoding of custom types below.
type Response1 struct {
  Page   int
  Fruits []string
}
type Response2 struct {
  Page   int      `json:"page"`
  Fruits []string `json:"fruits"`
}

func main() {
  // First we'll look at encoding basic data types to JSON strings. Here are some examples for atomic values
  bolB, _ := json.Marshal(true)
  fmt.Println(string(bolB))

  intB, _ := json.Marshal(1)
  fmt.Println(string(intB))

  fltB, _ := json.Marshal(2.34)
  fmt.Println(string(fltB))

  strB, _ := json.Marshal("gopher")
  fmt.Println(string(strB))

  // And here are some for slices and maps, which encode
  // to JSON arrays and objects as you'd expect.
  slcD := []string{"apple", "peach", "pear"}
  slcB, _ := json.Marshal(slcD)
  fmt.Println(string(slcB))

  mapD := map[string]int{"apple": 5, "lettuce": 7}
  mapB, _ := json.Marshal(mapD)
  fmt.Println(string(mapB))

  // The JSON package can automatically encode your custom data types. It will only include exported
  // fields in the encoded output and will by default use those names as the JSON keys.
  res1D := &Response1{
      Page:   1,
      Fruits: []string{"apple", "peach", "pear"}}
  res1B, _ := json.Marshal(res1D)
  fmt.Println(string(res1B))

  // You can use tags on struct field declarations to customize the encoded JSON key names. Check the
  // definition of `Response2` above to see an example of such tags.
  res2D := &Response2{
      Page:   1,
      Fruits: []string{"apple", "peach", "pear"}}
  res2B, _ := json.Marshal(res2D)
  fmt.Println(string(res2B))

  // Now let's look at decoding JSON data into Go values. Here's an example for a generic data structure.
  byt := []byte(`{"num":6.13,"strs":["a","b"]}`)

  // We need to provide a variable where the JSON package can put the decoded data.
  // This `map[string]interface{}` will hold a map of strings to arbitrary data types.
  var dat map[string]interface{}

  // Here's the actual decoding, and a check for associated errors.
  if err := json.Unmarshal(byt, &dat); err != nil {
      panic(err)
  }
  fmt.Println(dat)

  // In order to use the values in the decoded map, we'll need to cast them to their appropriate type.
  // For example here we cast the value in `num` to the expected `float64` type.
  num := dat["num"].(float64)
  fmt.Println(num)

  // Accessing nested data requires a series of casts.
  strs := dat["strs"].([]interface{})
  str1 := strs[0].(string)
  fmt.Println(str1)

  // We can also decode JSON into custom data types. This has the advantages of adding additional type-safety to our programs and eliminating the
  // need for type assertions when accessing the decoded data.
  str := `{"page": 1, "fruits": ["apple", "peach"]}`
  res := Response2{}
  json.Unmarshal([]byte(str), &res)
  fmt.Println(res)
  fmt.Println(res.Fruits[0])

  // In the examples above we always used bytes and strings as intermediates between the data and JSON representation on standard out. We can also
  // stream JSON encodings directly to `os.Writer`s like `os.Stdout` or even HTTP response bodies.
  enc := json.NewEncoder(os.Stdout)
  d := map[string]int{"apple": 5, "lettuce": 7}
  enc.Encode(d)
}