Json and Go
Reference https://blog.go-zh.org/json-a...
Encoding
Encode的基本用法是
package mainimport ("encoding/json""fmt""os" )type Message struct {Name stringBody stringTime int64 }func main() {message := Message{"Tom", "Hello", 1294706395881547000}b, err := json.Marshal(message)if err != nil {fmt.Fprintf(os.Stderr, "Failed to Marshal!")os.Exit(1)}fmt.Printf("%s", b) }輸出為:
{"Name":"Tom","Body":"Hello","Time":1294706395881547000} func Marshal(v interface{}) ([]byte, error)Only data structures that can be represented as valid JSON will be encoded:
- JSON objects only support string as keys.
- Channel, complex, and function types cannot be encoded.
- Cyclic data structures are not supported.
- Pointers will be encoded as the values they point to(or null if the pointer is nil)
json package 只能access the exportede fields. 也就是首字母大寫的field. 也就是在data structure中的首字母大寫的field才會(huì)present in JSON output
Decoding
// We must first create a place where the decoded data will be stored var output Message // Please note that passing the pointer to output decodeErr := json.Unmarshal(b, &output) if decodeErr != nil {fmt.Fprintf(os.Stderr, "Failed to Unmarshal json data!err:%s", err)os.Exit(1) }fmt.Printf("%+v\n", output)Unmarshal是怎么確認(rèn)json field與data structure的對(duì)應(yīng)關(guān)系呢?,其實(shí)是通過(guò)以下來(lái)判斷的(優(yōu)先級(jí)從高到低).比如對(duì)于JSON Field "Foo"來(lái)說(shuō),
- An exported field with a tag of "Foo".
- An exported field named "Foo"
- An exported field named "FOO" or "FoO" or some other case-insensitive match of "Foo"
總結(jié)下來(lái)是: Tag -> Foo -> FOO(case-insensitive match)
tag的判定規(guī)則如下
如果json data 與data structure中只有部分field匹配怎么辦?
var unmatchedOutput UnmatchMessage message1 := //` `代表原生字符串面值,沒有轉(zhuǎn)義操作,全是字符串的字面值 []byte{`{"Name":"Tom","Body":"Hello","Time":1294706395881547000}`} decodeErr1 := json.Unmarshal(b, &unmatchedOutput) if decodeErr1 != nil {fmt.Fprintf(os.Stderr, "Failed to unmarshal json data! err:", err)os.Exit(1) } fmt.Printf("%+v\n", unmatchedOutput)輸出為
{Name:Tom Boy: Tim:0}從上看出,Unmarshal只會(huì)decode符合上述3條件的field!
This behavior is particularly useful when you wish to pick only a few specific fields out of a large JSON blob.
Generic JSON with interface{}
Decoding arbitrary data
以上2章先跳過(guò)去
Reference Types
Unmarshal會(huì)為Reference Types自動(dòng)allocated a memory. 注意這里僅僅為在json 中存在的data allocate memory.
package mainimport ("encoding/json""fmt""os" )type FamilyMember struct {Name stringAge intParents []string }func main() {family := FamilyMember{"Andy", 26, []string{"Tom", "Lucy"}}b, err := json.Marshal(family)if err != nil {fmt.Fprintf(os.Stderr, "Failed to Marshal family!err:%s", err)os.Exit(1)}fmt.Printf("%s\n", b)// 注意,此時(shí)Parents slice是nil. 在Unmarshal時(shí),會(huì)自動(dòng)為其allcated memory.var output FamilyMemberdecodeErr := json.Unmarshal(b, &output)if decodeErr != nil {fmt.Fprintf(os.Stderr, "Failed to unmarshal!err:%s", err.Error())os.Exit(1)}fmt.Printf("%+v\n", output) }對(duì)于指針也是一樣的
package mainimport ("encoding/json""fmt""os" )type Bar int type Foo struct {Bar *Bar }func main() {b := []byte(`{"Bar":1234}`)var data Fooerr := json.Unmarshal(b, &data)if err != nil {fmt.Fprintf(os.Stderr, "Failed to unmarshal!err:%s", err.Error())os.Exit(1)}fmt.Printf("%+v\n", data)fmt.Printf("%+v\n", *(data.Bar)) }輸出為:
{Bar:0xc42001a120} // 注意此時(shí)的地址不為nil了,因?yàn)樵赨nmarshal已經(jīng)為其allocated了memory 1234但是需要注意,Unmarshal只會(huì)為json data匹配的field 分配內(nèi)存,對(duì)于沒有匹配的,可能還是nil. 所以對(duì)于如下的structure,在使用之前還需要認(rèn)為的判斷是否為nil.
type IncomingMessage struct {Cmd *CommandMsg *Message }Streaming Encoders and Decoders
package mainimport ("encoding/json""log""os" )func main() {dec := json.NewDecoder(os.Stdin)enc := json.NewEncoder(os.Stdout)for {var v map[string]interface{}if err := dec.Decode(&v); err != nil {log.Println(err)return}for k := range v {if k != "Name" {delete(v, k)}}if err := enc.Encode(&v); err != nil {log.Println(err)}} }總結(jié)
以上是生活随笔為你收集整理的Json and Go的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: leetcode203.移除链表元素
- 下一篇: 驼峰设计 PPT设计网站