Go語言裡的Json

2021-09-26 22:53:07 字數 2390 閱讀 9932

json是一種輕量級資料交換格式,具有靈活、易於閱讀的特點,在網際網路行業有廣泛的應用。go語言執行時裡自帶了encoding/json包,提供了marshal()和unmarshal()兩個函式進行編碼和解碼,兩個函式原型如下:

func marshal(v inte***ce{}) (byte, error)

func unmarshal(data byte, v inte***ce{}) error

廢話少說,直接上例子:

package main

import (

"fmt"

"encoding/json"

)type foo struct

func main() `)

var f foo

json.unmarshal(data, &f)

fmt.printf("%s is %d years old.\n", f.name, f.age)

output, _ := json.marshal(&f)

fmt.println(string(output))

}

用法很簡單,不過有兩個問題需要說明一下:

結構體foo裡的字段必須是大寫字母開頭,否則將不能從json中解析出對應的字段。原因是go語言約定乙個包中只有首字母大寫的符號才被匯出給其他包使用。json.unmarshal()函式是在另外乙個包裡的,所以如果欄位名小寫,就無法進行賦值。

這種寫法預設把json裡的字段賦值給結構體foo裡的同名字段,但是兩者的欄位名並不總是能保持一致,比如json裡的欄位名可能是小寫的name和age。這種情況下就需要手動指定欄位的對應關係:

type foo struct

結構體foo裡的字段不但可以是基本型別,也可以是其他的結構體,比如下面這個例子:

type employment struct 

type foo struct

func main() }`)

var f foo

json.unmarshal(data, &f)

fmt.printf("%s is %d years old.\n", f.name, f.age)

output, _ := json.marshal(&f)

fmt.println(string(output))

}

前面這兩個例子裡,json的結構都是已經確定了的,因此才可以預先定義好結構體,然後用marshal()和unmarshal()在go物件和json串之間進行轉換。有時候在解析之前我們可能並不知道json物件裡有哪些字段,這就需要一種更靈活的處理方式。在python裡,json.loads()直接將json串轉換成字典。類似的,在go語言裡,可以用把字段不確定的json串轉換成map。看下面這個例子:

type foo struct  `json:"extra"`

}func main() ,

"extra": }`)

var f foo

json.unmarshal(data, &f)

fmt.printf("%s is %d years old and works at %s.\n", f.name, f.age, f.job.company)

fmt.printf("he is %s and has %d childrens.\n", f.extra["marital status"].(string), int(f.extra["childrens"].(float64)))

output, _ := json.marshal(&f)

fmt.println(string(output))

}

extra對應了json物件裡結構不確定的extra欄位。go語言的map在宣告時必須指定key和value的型別(這點遠不如python靈活),但是extra裡的字段可能是不同型別,因此這個例子裡使用了inte***ce作為value型別。inte***ce也就是「介面」,go語言裡任何資料型別都是某種介面,因此inte***ce型別可以指代任何型別。當然我們也可以自定義inte***ce型別,這不在本文的討論範圍之內。按照我的理解,inte***ce型別在這裡的作用類似於c語言裡的void *。

還有一點值得一提的是,例子裡的childrens字段值雖然是整數,但是被解析成了float64型別。在json的定義中,值的型別不分整型和浮點型,只有乙個number型別,因此在我們沒有指定欄位和型別的情況下,unmarshal()函式把所有number型別的值都當作float64。我也是在寫這篇文章的時候才發現這一點的。

有了這些技巧,基本上已經能應付絕大部分的json處理任務了。如果還是覺得不夠好用,可以嘗試一下bit.ly的******json,或者效能更好的easyjson。

Go語言裡的Json

json是一種輕量級資料交換格式,具有靈活 易於閱讀的特點,在網際網路行業有廣泛的應用。go語言執行時裡自帶了encoding json包,提供了marshal 和unmarshal 兩個函式進行編碼和解碼,兩個函式原型如下 func marshal v inte ce byte,error fun...

Go語言裡channel的死鎖

最近看了下go語言並寫了些示例 在用到channel的時候報了個奇怪的錯誤然後退出 fatal error all goroutines are asleep deadlock 在stackoverflow上搜到 查了查,出錯的 如下 func chanfunc c chan int,d chan ...

Go語言標準庫Json的使用

github上別人做的封裝,挺好用的,推薦一下 這個內建的標準庫用起來還是很煩得,要知道對方發過來的type,不然只能自己分析反射.package main import encoding json fmt type status slice int type info struct func ma...