1. golang 中 json 轉 struct
<1. 使用 json.Unmarshal 時,結構體的每一項必須是導出項(import field)。也就是說結構體的 key 對應的首字母必須為大寫。請看下面的例子:
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) }
輸出的結果如下:
{ 0}
從結果可以看出,json 數據並沒有寫入 Person 結構體中。結構體 key 首字母大寫的話就可以,修改后:
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) }
打印結果如下:
{liangyongxing 12}
從以上結果我們可以發現一個很重要的信息,json 里面的 key 和 struct 里面的 key 一個是小寫一個是大寫,即兩者大小寫並沒有對上。從這里我們就可以得出一個結論,要想能夠附上值需要結構體中的變量名首字母大寫,而在轉換的 json 串中大小寫都可以,即在 json 傳中字段名稱大小寫不敏感。那么經過驗證發現,在 json 中如果寫成如下方式:
jsonStr := ` { "NaMe":"liangyongxing", "agE":12 } `
最終結果仍然是有值的,那么就驗證了我們上面的結論,json 串中對字段名大小寫不敏感(不一定是首字母,這點需要注意)
<2. 在結構體中是可以引入 tag 標簽的,這樣在匹配的時候 json 串對應的字段名需要與 tag 標簽中定義的字段名匹配,當然在 tag 中定義的名稱就不需要首字母大寫了,且對應的 json 串中字段名稱仍然大小寫不敏感,和上面的結論一致。(注意:此時結構體中對應的字段名可以不用和匹配的一致,但是也必須首字母大寫,只有大寫的才是可對外提供訪問的)
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) }
這樣輸出的結果如下:
{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 }
打印結果如下所示:
/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