go語言學習-json 解析

json 解析 encoding/json 包

Json 是一種比 XML 更輕量級的數據交換格式,易於人們閱讀和編寫,也易於程序解析 和生成。是較理想的、跨平臺的、跨語言的數據交換語言,應用十分普遍。json

快速使用

// int, string Marshal 之後值不一樣

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

	var mapC map[string]uint16
	err := json.Unmarshal(mapB, &mapC)
	if err != nil {
		fmt.Println("=====", err)
	}

	fmt.Println(mapC)
		    

結果
{"apple":5,"lettuce":"5"}
===== json: cannot unmarshal string into Go value of type uint16
map[apple:5 lettuce:0]

##用於須要使用流的場景:數組

1.func (enc *Encoder) Encode(v interface{}) error 對象序列化成字符串安全

2.func (dec *Decoder) Decode(v interface{}) error 字符串序列號成對象app

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Student struct {
	Name string
	Age  int
}

func main() {
	f, err := os.Create("data.dat")
	if err != nil {
		fmt.Println(err)
	}
	s := &Student{"張三", 19} //建立 encode 對像
	encoder := json.NewEncoder(f) //將 s 序列化到文件中
	encoder.Encode(s)

	//重置文件指針到開始位置
	f.Seek(0, os.SEEK_SET)
	decoder := json.NewDecoder(f)
	var s1 Student //從文件中反序列化成對像
	decoder.Decode(&s1)
	fmt.Println(s1)
}

##不須要流的場景ui

3.func Marshal(v interface{}) ([]byte, error) 對象序列化成字符串編碼

4.func Unmarshal(data []byte, v interface{}) error 字符串反序列號對象spa

package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	Name string `json:"userName"`
	Age  int
}

func main() {
	s := &Student{"張三", 19} //將 s 編碼爲 json
	buf, err := json.Marshal(s)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(string(buf))//將 json 字符串轉換成 Student 對像
	var s1 Student
	json.Unmarshal(buf, &s1)
	fmt.Println(s1)
}
  • Unmarshal 最大的特色就是,能夠把 json 解析到一個 **map[string]interface{}**裏。
package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	str := `{"userName":"張三","Age":19}`
	var m map[string]interface{}
	json.Unmarshal([]byte(str), &m)
	for k, v := range m {
		switch v.(type) {
		case float64:
			fmt.Println(k, " 是 int 類型,值爲:", v)
		case string:
			fmt.Println(k, " 是 string 類型,值爲:", v)
		default:
			fmt.Println(k, "沒法誤用別的類型")
		}
	}
}

在上面的代碼中 Age 明明是 int 解析後成了 float64。這是由於 Go 中規定, **指針

  • Json 中的布爾值會被解析爲布爾值 (booleans->bool),
  • Json 中的全部數字(整型,浮點型)將被解析爲 float64 (numbers->float64),
  • Json 中的 string,被解析爲 string 類型 (strings->string),
  • Json 中的數組被解析爲 interface{}數組 ([]int->[]interface{}),
  • Json 中的空值解爲 nil (null->nil)。 **

轉帖例子:http://www.tuicool.com/articles/zQJFNrfcode

package main
 
import "encoding/json"
import "fmt"
import "os"
 
//  咱們使用兩個結構體來演示自定義數據類型的JSON數據編碼和解碼。
type Response1 struct {
  Page   int
  Fruits []string
}
type Response2 struct {
  Page   int	  `json:"page"`
  Fruits []string `json:"fruits"`
}
 
func main() {
 
  // 首先咱們看一下將基礎數據類型編碼爲JSON數據
  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))
 
  // 這裏是將切片和字典編碼爲JSON數組或對象
  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))
 
  // JSON包能夠自動地編碼自定義數據類型。結果將只包括自定義
  // 類型中的可導出成員的值而且默認狀況下,這些成員名稱都做
  // 爲JSON數據的鍵
  res1D := &Response1{
    Page:   1,
    Fruits: []string{"apple", "peach", "pear"}}
  res1B, _ := json.Marshal(res1D)
  fmt.Println(string(res1B))
 
  // 你可使用tag來自定義編碼後JSON鍵的名稱
  res2D := &Response2{
    Page:   1,
    Fruits: []string{"apple", "peach", "pear"}}
  res2B, _ := json.Marshal(res2D)
  fmt.Println(string(res2B))
 
  // 如今咱們看看解碼JSON數據爲Go數值
  byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
 
  // 咱們須要提供一個變量來存儲解碼後的JSON數據,這裏
  // 的`map[string]interface{}`將以Key-Value的方式
  // 保存解碼後的數據,Value能夠爲任意數據類型
  var dat map[string]interface{}
 
  // 解碼過程,並檢測相關可能存在的錯誤
  if err := json.Unmarshal(byt, &dat); err != nil {
    panic(err)
  }
  fmt.Println(dat)
 
  // 爲了使用解碼後map裏面的數據,咱們須要將Value轉換爲
  // 它們合適的類型,例如咱們將這裏的num轉換爲指望的float64
  num := dat["num"].(float64)
  fmt.Println(num)
 
  // 訪問嵌套的數據須要一些類型轉換
  strs := dat["strs"].([]interface{})
  str1 := strs[0].(string)
  fmt.Println(str1)
 
  // 咱們還能夠將JSON解碼爲自定義數據類型,這有個好處是能夠
  // 爲咱們的程序增長額外的類型安全而且不用再在訪問數據的時候
  // 進行類型斷言
  str := `{"page": 1, "fruits": ["apple", "peach"]}`
  res := &Response2{}
  json.Unmarshal([]byte(str), &res)
  fmt.Println(res)
  fmt.Println(res.Fruits[0])
 
  // 上面的例子中,咱們使用bytes和strings來進行原始數據和JSON數據
  // 之間的轉換,咱們也能夠直接將JSON編碼的數據流寫入`os.Writer`
  // 或者是HTTP請求回覆數據。
  enc := json.NewEncoder(os.Stdout)
  d := map[string]int{"apple": 5, "lettuce": 7}
  enc.Encode(d)
}

outputserver

true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"Page":1,"Fruits":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
map[num:6.13 strs:[a b]]
6.13
a
&{1 [apple peach]}
apple
{"apple":5,"lettuce":7}

json 中參數是數組

當struct中須要數組[]interface{}形如這樣的參數時,json傳的格式是**"params":["hello world!"] **

json中用數組用[]表示,先後不加"" 引號,內部不須要\ 轉義。

package main

import (
	"encoding/json"
	"fmt"
)

//RPCParam rpc的data json數據
type RPCParam struct {
	Version   string        `json:"version"`
	User      string        `json:"user"`
	Password  string        `json:"password"`
	Timestamp int64         `json:"-"`
	Class     string        `json:"class"`
	Method    string        `json:"method"`
	Params    []interface{} `json:"params,omitempty"`
}

func main() {
	str := `{"version":"2.0","user":"","password":"","timestamp":1482723555,"class":"RpcClient_acsdispatcher","method":"serveraddr","params":["hello world!"]}`
	var n RPCParam
	err := json.Unmarshal([]byte(str), &n)
	fmt.Println(err, n)

}
相關文章
相關標籤/搜索