先來看一個正常的例子:
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
Name string
Id int
}
func main() {
s := Student{
Name:"chenchao",
Id:123,
}
buf, err := json.Marshal(s)
if err != nil{
fmt.Println(err)
}
fmt.Println(string(buf))
}
結果:
{"Name":"chenchao","Id":123}
再來看一個異常的例子:
我們將結構體中的“Name”改寫為“name”再看結果
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
name string
Id int
}
func main() {
s := Student{
name:"chenchao",
Id:123,
}
buf, err := json.Marshal(s)
if err != nil{
fmt.Println(err)
}
fmt.Println(string(buf))
}
結果:
{"Id":123}
會發(fā)現(xiàn)json后的數據Name不見了。
原因:
在go語言中的小寫開頭的變量或者函數為私有的,只限于當前文件可見介衔。但是json方法所在位置處在其它包中不傅。所以在json時小寫的name是不能被發(fā)現(xiàn)的土砂。這樣可以做到選擇性的序列化數據咸作。
解決
第一種:
將小寫的name改為Name
但破壞了數據可見性
第二種:
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
name string
Id int
}
// 在執(zhí)行json Marshal之前會先執(zhí)行此處的方法
func (s *Student)MarshalJSON() ([]byte, error) {
type JsonStudent struct {
Name string
Id int
}
w := JsonStudent{Name:s.name, Id:s.Id}
return json.Marshal(w)
}
func (s *Student) UnmarshalJSON(buf []byte) error {
// 這里專門處理json后的數據
type JsonStudent struct {
Name string
Id int
}
w := JsonStudent{Name:s.name, Id:s.Id}
return json.Unmarshal(buf, &w)
}
func main() {
s := &Student{
name:"chenchao",
Id:123,
}
buf, err := json.Marshal(s)
if err != nil{
fmt.Println(err)
}
fmt.Println("json dumps ",string(buf))
// unmarshal
_ =json.Unmarshal(buf, s) // 參數分別為 json數據 相對的數據變量
fmt.Println("json.load", s)
}
再來看一個相對復雜的例子:
package main
import (
"encoding/json"
"fmt"
)
var classroom = make(map[string]*Classroom)
type Classroom struct {
students map[string]*Student
}
type Student struct {
Name string
Id int
}
func (s *Classroom) MarshalJSON() ([]byte, error) {
//m := make(map[string]interface{})
//m["students"] = s.students
return json.Marshal(s.students)
}
func (s *Classroom) UnmarshalJSON(buf []byte) error {
cc := json.Unmarshal(buf, &s.students)
return cc
}
func main() {
s1 := Student{Name:"chenchao", Id:123}
s2 := Student{Name:"zhangsan", Id:234}
st := make(map[string]*Student)
st["chenchao"] = &s1
st["zhangsan"] = &s2
class1 := Classroom{
students: st,
}
classroom["class1"] = &class1
buf, err := json.Marshal(classroom)
if err != nil{
fmt.Println(err)
}
fmt.Println(string(buf))
err = json.Unmarshal(buf, &classroom)
if err !=nil {
fmt.Println("json load err: ", err)
}
for k,v := range classroom{
fmt.Println(k)
for s,t := range v.students{
fmt.Println(s, t)
}
}
}