Go json私有數(shù)據(jù)結(jié)果為nil

先來(lái)看一個(gè)正常的例子:

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))
}

結(jié)果:

{"Name":"chenchao","Id":123}

再來(lái)看一個(gè)異常的例子:
我們將結(jié)構(gòu)體中的“Name”改寫為“name”再看結(jié)果

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))
}

結(jié)果:

{"Id":123}

會(huì)發(fā)現(xiàn)json后的數(shù)據(jù)Name不見了。

原因:

在go語(yǔ)言中的小寫開頭的變量或者函數(shù)為私有的,只限于當(dāng)前文件可見。但是json方法所在位置處在其它包中。所以在json時(shí)小寫的name是不能被發(fā)現(xiàn)的。這樣可以做到選擇性的序列化數(shù)據(jù)。

解決

第一種:
將小寫的name改為Name
但破壞了數(shù)據(jù)可見性

第二種:

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    name string
    Id int
}
// 在執(zhí)行json Marshal之前會(huì)先執(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后的數(shù)據(jù)
    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)       // 參數(shù)分別為 json數(shù)據(jù)  相對(duì)的數(shù)據(jù)變量
    fmt.Println("json.load", s)
}

再來(lái)看一個(gè)相對(duì)復(fù)雜的例子:

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)
        }
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容