Go_14:GoLang中 json、map、struct 之間的相互轉化

1. golang 中 json 轉 struct

  <1. 使用 json.Unmarshal 時,結構體的每一項必須是導出項(import field)。也就是說結構體的 key 對應的首字母必須爲大寫。請看下面的例子:git

package commontest

import (
    "testing"
    "encoding/json"
)

type Person struct {
    name string
    age int
}

func TestStruct2Json(t *testing.T) {
    jsonStr := `
    {
        "name":"liangyongxing",
        "age":12
    }
    `
    var person Person
    json.Unmarshal([]byte(jsonStr), &person)
    t.Log(person)
}

輸出的結果以下:github

{ 0}

   從結果能夠看出,json 數據並無寫入 Person 結構體中。結構體 key 首字母大寫的話就能夠,修改後:golang

package commontest

import (
    "testing"
    "encoding/json"
)

type Person struct {
    Name string
    Age int
}

func TestStruct2Json(t *testing.T) {
    jsonStr := `
    {
        "name":"liangyongxing",
        "age":12
    }
    `
    var person Person
    json.Unmarshal([]byte(jsonStr), &person)
    t.Log(person)
}

打印結果以下:json

{liangyongxing 12}

   從以上結果咱們能夠發現一個很重要的信息,json 裏面的 key 和 struct 裏面的 key 一個是小寫一個是大寫,即二者大小寫並無對上。從這裏咱們就能夠得出一個結論,要想可以附上值須要結構體中的變量名首字母大寫,而在轉換的 json 串中大小寫均可以,即在 json 傳中字段名稱大小寫不敏感。那麼通過驗證發現,在 json 中若是寫成以下方式:bash

jsonStr := `
    {
        "NaMe":"liangyongxing",
        "agE":12
    }
    `

  最終結果仍然是有值的,那麼就驗證了咱們上面的結論,json 串中對字段名大小寫不敏感(不必定是首字母,這點須要注意)spa

  <2. 在結構體中是能夠引入 tag 標籤的,這樣在匹配的時候 json 串對應的字段名須要與 tag 標籤中定義的字段名匹配,固然在 tag 中定義的名稱就不須要首字母大寫了,且對應的 json 串中字段名稱仍然大小寫不敏感,和上面的結論一致。(注意:此時結構體中對應的字段名能夠不用和匹配的一致,可是也必須首字母大寫,只有大寫的纔是可對外提供訪問的)code

package commontest

import (
    "testing"
    "encoding/json"
)

//這裏對應的 N 和 A 不能爲小寫,首字母必須爲大寫,這樣纔可對外提供訪問,具體 json 匹配是經過後面的 tag 標籤進行匹配的,與 N 和 A 沒有關係
//tag 標籤中 json 後面跟着的是字段名稱,都是字符串類型,要求必須加上雙引號,不然 golang 是沒法識別它的類型
type Person struct {
    N string     `json:"name"`
    A int        `json:"age"`
}

func TestStruct2Json(t *testing.T) {
    jsonStr := `
    {
        "name":"liangyongxing",
        "age":12
    }
    `
    var person Person
    json.Unmarshal([]byte(jsonStr), &person)
    t.Log(person)
}

這樣輸出的結果以下:blog

{liangyongxing 12}

   固然,你也能夠再作一個實驗,驗證 tag 標籤中對應的字段名稱大小寫不敏感,這裏就不作冗餘介紹了。字符串

2. golang 中 struct 轉 json 串

 1 package commontest
 2 
 3 import (
 4     "testing"
 5     "encoding/json"
 6 )
 7 
 8 func TestStruct2Json(t *testing.T) {
 9     p := Person{
10         Name: "liangyongxing",
11         Age: 29,
12     }
13 
14     t.Logf("Person 結構體打印結果:%v", p)
15 
16     //Person 結構體轉換爲對應的 Json
17     jsonBytes, err := json.Marshal(p)
18     if err != nil {
19         t.Fatal(err)
20     }
21     t.Logf("轉換爲 json 串打印結果:%s", string(jsonBytes))
22 }

打印結果以下所示:get

/usr/local/go/bin/go test -v commontest -run ^TestStruct2Json$
	struct2json_test.go:14: Person 結構體打印結果:{liangyongxing 29}
	struct2json_test.go:21: 轉換爲 json 串打印結果:{"name":"liangyongxing","age":29}
ok  	commontest	0.006s

 3. golang 中 json 轉 map

package commontest

import (
    "testing"
    "encoding/json"
)

func TestJson2Map(t *testing.T) {
    jsonStr := `
    {
        "name":"liangyongxing",
        "age":12
    }
    `
    var mapResult map[string]interface{}
    //使用 json.Unmarshal(data []byte, v interface{})進行轉換,返回 error 信息
    if err := json.Unmarshal([]byte(jsonStr), &mapResult); err != nil {
        t.Fatal(err)
    }
    t.Log(mapResult)
}

打印結果信息以下:

/usr/local/go/bin/go test -v commontest -run ^TestJson2Map$
	json2map_test.go:19: map[name:liangyongxing age:12]
ok  	commontest	0.007s

4. golang 中 map 轉 json 串

package commontest

import (
    "testing"
    "encoding/json"
)

func TestMap2Json(t *testing.T) {
    mapInstance := make(map[string]interface{})
    mapInstance["Name"] = "liang637210"
    mapInstance["Age"] = 28
    mapInstance["Address"] = "北京昌平區"

    jsonStr, err := json.Marshal(mapInstance)

    if err != nil {
        t.Fatal(err)
    }

    t.Logf("Map2Json 獲得 json 字符串內容:%s", jsonStr)
}

打印結果以下:

/usr/local/go/bin/go test -v commontest -run ^TestMap2Json$
	map2json_test.go:20: Map2Json 獲得 json 字符串內容:{"Address":"北京昌平區","Age":28,"Name":"liang637210"}
ok  	commontest	0.008s

5. golang 中 map 轉 struct

  這個轉換網上有比較完整的項目,已經上傳到對應的 github 上了,須要下載以後使用:

  $ go get github.com/goinggo/mapstructure

   以後咱們就能夠直接使用它提供的方法將 map 轉換爲 struct,讓咱們直接上代碼吧

package commontest

import (
    "testing"
    "github.com/goinggo/mapstructure"
)

func TestMap2Struct(t *testing.T) {
    mapInstance := make(map[string]interface{})
    mapInstance["Name"] = "liang637210"
    mapInstance["Age"] = 28

    var person Person
    //將 map 轉換爲指定的結構體
    if err := mapstructure.Decode(mapInstance, &person); err != nil {
        t.Fatal(err)
    }
    t.Logf("map2struct後獲得的 struct 內容爲:%v", person)
}

打印結果以下:

/usr/local/go/bin/go test -v commontest -run ^TestMap2Struct$
	map2struct_test.go:18: map2struct後獲得的 struct 內容爲:{liang637210 28}
ok  	commontest	0.009s

6. golang 中 struct 轉 map

 1 package commontest
 2 
 3 import (
 4     "testing"
 5     "reflect"
 6 )
 7 
 8 type User struct {
 9     Id        int    `json:"id"`
10     Username    string    `json:"username"`
11     Password    string    `json:"password"`
12 }
13 
14 func Struct2Map(obj interface{}) map[string]interface{} {
15     t := reflect.TypeOf(obj)
16     v := reflect.ValueOf(obj)
17 
18     var data = make(map[string]interface{})
19     for i := 0; i < t.NumField(); i++ {
20         data[t.Field(i).Name] = v.Field(i).Interface()
21     }
22     return data
23 }
24 
25 func TestStruct2Map(t *testing.T) {
26     user := User{5, "zhangsan", "password"}
27     data := Struct2Map(user)
28     t.Logf("struct2map獲得的map內容爲:%v", data)
29 }

打印結果以下:

/usr/local/go/bin/go test -v commontest -run ^TestStruct2Map$
	struct2map_test.go:28: struct2map獲得的map內容爲:map[Id:5 Username:zhangsan Password:password]
ok  	commontest	0.007s
相關文章
相關標籤/搜索