Golang語言JSON解碼函數(shù)Unmarshal的使用
前言
工作中我們經(jīng)常會遇到解碼JSON格式的數(shù)據(jù),本文通過4個(gè)示例介紹工作中常用到的四種 JSON格式。在 Golang語言中,通常是使用標(biāo)準(zhǔn)庫的encoding/json包中的函數(shù)Unmarshal解碼JSON格式的數(shù)據(jù),下面我們先介紹一下該函數(shù)如何使用,再通過4個(gè)示例代碼來演示一下如何在Golang中解碼常見的4種JSON格式的數(shù)據(jù)。
func Unmarshal
func Unmarshal(data []byte, v interface{}) error
Unmarshal函數(shù)解析json編碼的數(shù)據(jù)并將結(jié)果存入v指向的值。
Unmarshal和Marshal做相反的操作,必要時(shí)申請映射、切片或指針,有如下的附加規(guī)則:
要將json數(shù)據(jù)解碼寫入一個(gè)指針,Unmarshal函數(shù)首先處理json數(shù)據(jù)是json字面值null的情況。此時(shí),函數(shù)將指針設(shè)為nil;否則,函數(shù)將json數(shù)據(jù)解碼寫入指針指向的值;如果指針本身是nil,函數(shù)會先申請一個(gè)值并使指針指向它。
要將json數(shù)據(jù)解碼寫入一個(gè)結(jié)構(gòu)體,函數(shù)會匹配輸入對象的鍵和Marshal使用的鍵(結(jié)構(gòu)體字段名或者它的標(biāo)簽指定的鍵名),優(yōu)先選擇精確的匹配,但也接受大小寫不敏感的匹配。
要將json數(shù)據(jù)解碼寫入一個(gè)接口類型值,函數(shù)會將數(shù)據(jù)解碼為如下類型寫入接口:
bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
如果一個(gè)JSON值不匹配給出的目標(biāo)類型,或者如果一個(gè)json數(shù)字寫入目標(biāo)類型時(shí)溢出,Unmarshal函數(shù)會跳過該字段并盡量完成其余的解碼操作。如果沒有出現(xiàn)更加嚴(yán)重的錯誤,本函數(shù)會返回一個(gè)描述第一個(gè)此類錯誤的詳細(xì)信息的UnmarshalTypeError。
JSON的null值解碼為go的接口、指針、切片時(shí)會將它們設(shè)為nil,因?yàn)閚ull在json里一般表示“不存在”。 解碼json的null值到其他go類型時(shí),不會造成任何改變,也不會產(chǎn)生錯誤。
當(dāng)解碼字符串時(shí),不合法的utf-8或utf-16代理(字符)對不視為錯誤,而是將非法字符替換為unicode字符U+FFFD。
普通JSON
示例代碼:
package main import ( ? ?"encoding/json" ? ?"fmt" ) // Actress 女演員 type Actress struct { ? ?Name ? ? ? string ? ?Birthday ? string ? ?BirthPlace string ? ?Opus ? ? ? []string } func main() { ? ?// 普通JSON ? ?// 因?yàn)閖son.UnMarshal() 函數(shù)接收的參數(shù)是字節(jié)切片, ? // 所以需要把JSON字符串轉(zhuǎn)換成字節(jié)切片。 ? jsonData := []byte(`{ ? ? ? "name":"迪麗熱巴", ? ? ? "birthday":"1992-06-03", ? ? ? "birthPlace":"新疆烏魯木齊市", ? ? ? "opus":[ ? ? ? ? ?"《阿娜爾罕》", ? ? ? ? ?"《逆光之戀》", ? ? ? ? ?"《克拉戀人》" ? ? ? ] ? ?}`) ? ?var actress Actress ? ?err := json.Unmarshal(jsonData, &actress) ? ?if err != nil { ? ? ? fmt.Println("error:", err) ? ? ? return ? ?} ? ?fmt.Printf("姓名:%s\n", actress.Name) ? ?fmt.Printf("生日:%s\n", actress.Birthday) ? ?fmt.Printf("出生地:%s\n", actress.BirthPlace) ? ?fmt.Println("作品:") ? ?for _, val := range actress.Opus { ? ? ? fmt.Println("\t", val) ? ?} }
運(yùn)行結(jié)果:
姓名:迪麗熱巴
生日:1992-06-03
出生地:新疆烏魯木齊市
作品:
《阿娜爾罕》
《逆光之戀》
《克拉戀人》
JSON內(nèi)嵌普通JSON
示例代碼:
package main import ( ? ?"encoding/json" ? ?"fmt" ) // Opus 作品 type Opus struct { ? ?Date string ? ?Title string } // Actress 女演員 type Actress struct { ? ?Name ? ? ? string ? ?Birthday ? string ? ?BirthPlace string ? ?Opus ? ? ? Opus } func main () { ? ?// JSON嵌套普通JSON ? ?jsonData := []byte(`{ ? ? ? "name":"迪麗熱巴", ? ? ? "birthday":"1992-06-03", ? ? ? "birthPlace":"新疆烏魯木齊市", ? ? ? "opus": { ? ? ? ? ?"Date":"2013", ? ? ? ? ?"Title":"《阿娜爾罕》" ? ? ? } ? ?}`) ? ?var actress Actress ? ?err := json.Unmarshal(jsonData, &actress) ? ?if err != nil { ? ? ? fmt.Println("error:", err) ? ? ? return ? ?} ? ?fmt.Printf("姓名:%s\n", actress.Name) ? ?fmt.Printf("生日:%s\n", actress.Birthday) ? ?fmt.Printf("出生地:%s\n", actress.BirthPlace) ? ?fmt.Println("作品:") fmt.Printf("\t%s:%s", actress.Opus.Date, ? actress.Opus.Title)}
運(yùn)行結(jié)果:
姓名:迪麗熱巴
生日:1992-06-03
出生地:新疆烏魯木齊市
作品:
2013:《阿娜爾罕》
JSON內(nèi)嵌數(shù)組JSON
示例代碼:
package main import ( ? ?"encoding/json" ? ?"fmt" ) type Opus struct { ? ?Date string ? ?Title string } type Actress struct { ? ?Name string ? ?Birthday string ? ?BirthPlace string ? ?Opus []Opus } func main () { ? ?// JSON嵌套數(shù)組JSON ? ?jsonData := []byte(`{ ? ? ? "name":"迪麗熱巴", ? ? ? "birthday":"1992-06-03", ? ? ? "birthPlace":"新疆烏魯木齊市", ? ? ? "opus":[ ? ? ? ? ?{ ? ? ? ? ? ? "date":"2013", ? ? ? ? ? ? "title":"《阿娜爾罕》" ? ? ? ? ?}, ? ? ? ? ?{ ? ? ? ? ? ? "date":"2014", ? ? ? ? ? ? "title":"《逆光之戀》" ? ? ? ? ?}, ? ? ? ? ?{ ? ? ? ? ? ? "date":"2015", ? ? ? ? ? ? "title":"《克拉戀人》" ? ? ? ? ?} ? ? ? ] ? ?}`) ? ?var actress Actress ? ?err := json.Unmarshal(jsonData, &actress) ? ?if err != nil { ? ? ? fmt.Println("error:", err) ? ? ? return ? ?} ? ?fmt.Printf("姓名:%s\n", actress.Name) ? ?fmt.Printf("生日:%s\n", actress.Birthday) ? ?fmt.Printf("出生地:%s\n", actress.BirthPlace) ? ?fmt.Println("作品:") ? ?for _, val := range actress.Opus { ? ? ? fmt.Printf("\t%s - %s\n", val.Date, val.Title) ? ?} }
運(yùn)行結(jié)果:
姓名:迪麗熱巴
生日:1992-06-03
出生地:新疆烏魯木齊市
作品:
2013 - 《阿娜爾罕》
2014 - 《逆光之戀》
2015 - 《克拉戀人》
JSON內(nèi)嵌具有動態(tài)Key的JSON
示例代碼:
package main import ( ? ?"encoding/json" ? ?"fmt" ) // Opus 作品 type Opus struct { ? ?Type string ? ?Title string } // Actress 女演員 type Actress struct { ? ?Name string ? ?Birthday string ? ?BirthPlace string ? ?Opus map[string]Opus } func main () { ? ?jsonData := []byte(`{ ? ? ? "name":"迪麗熱巴", ? ? ? "birthday":"1992-06-03", ? ? ? "birthPlace":"新疆烏魯木齊市", ? ? ? "opus":{ ? ? ? ? ?"2013":{ ? ? ? ? ? ? "Type":"近代革命劇", ? ? ? ? ? ? "Title":"《阿娜爾罕》" ? ? ? ? ?}, ? ? ? ? ?"2014":{ ? ? ? ? ? ? "Type":"奇幻劇", ? ? ? ? ? ? "Title":"《逆光之戀》" ? ? ? ? ?}, ? ? ? ? ?"2015":{ ? ? ? ? ? ? "Type":"愛情劇", ? ? ? ? ? ? "Title":"《克拉戀人》" ? ? ? ? ?} ? ? ? } ? ?}`) ? ?var actress Actress ? ?err := json.Unmarshal(jsonData, &actress) ? ?if err != nil { ? ? ? fmt.Println("error:", err) ? ? ? return ? ?} ? ?fmt.Printf("姓名:%s\n", actress.Name) ? ?fmt.Printf("生日:%s\n", actress.Birthday) ? ?fmt.Printf("出生地:%s\n", actress.BirthPlace) ? ?fmt.Println("作品:") ? ?for index, value := range actress.Opus { ? ? ? fmt.Printf("\t日期:%s\n", index) ? ? ? fmt.Printf("\t\t分類:%s\n", value.Type) ? ? ? fmt.Printf("\t\t標(biāo)題:%s\n", value.Title) ? ?} }
運(yùn)行結(jié)果:
姓名:迪麗熱巴
生日:1992-06-03
出生地:新疆烏魯木齊市
作品:
日期:2013
分類:近代革命劇
標(biāo)題:《阿娜爾罕》
日期:2014
分類:奇幻劇
標(biāo)題:《逆光之戀》
日期:2015
分類:愛情劇
標(biāo)題:《克拉戀人》
總結(jié)
我們先是介紹了Golang標(biāo)準(zhǔn)庫的encoding/json包中的Unmarshal函數(shù),然后通過上面4個(gè)示例代碼,分別介紹了如何解碼以下4種JSON格式數(shù)據(jù):
JSON格式1:
{ ? ? "name":"迪麗熱巴", ? ? "birthday":"1992-06-03", ? ? "birthPlace":"新疆烏魯木齊市", ? ? "opus":[ ? ? ? ? "《阿娜爾罕》", ? ? ? ? "《逆光之戀》", ? ? ? ? "《克拉戀人》" ? ? ] }
JSON格式2:
{ "name":"迪麗熱巴", "birthday":"1992-06-03", "birthPlace":"新疆烏魯木齊市", "opus":{ "Date":"2013", "Title":"《阿娜爾罕》" } }
JSON格式3:
{ "name":"迪麗熱巴", "birthday":"1992-06-03", "birthPlace":"新疆烏魯木齊市", "opus":[ { "date":"2013", "title":"《阿娜爾罕》" }, { "date":"2014", "title":"《逆光之戀》" }, { "date":"2015", "title":"《克拉戀人》" } ] }
JSON格式4:
{ "name":"迪麗熱巴", "birthday":"1992-06-03", "birthPlace":"新疆烏魯木齊市", "opus":{ "2013":{ "Type":"近代革命劇", "Title":"《阿娜爾罕》" }, "2014":{ "Type":"奇幻劇", "Title":"《逆光之戀》" }, "2015":{ "Type":"愛情劇", "Title":"《克拉戀人》" } } }
到此這篇關(guān)于Golang語言JSON解碼函數(shù)Unmarshal的使用的文章就介紹到這了,更多相關(guān)Golang JSON Unmarshal內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語言異常panic和恢復(fù)recover用法實(shí)例
這篇文章主要介紹了go語言異常panic和恢復(fù)recover用法,實(shí)例分析了異常panic和恢復(fù)recover使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03GoLand 2020.3 正式發(fā)布有不少新功能(支持泛型)
這是 2020 年第 3 個(gè)版本,也是最后一個(gè)版本,你還將發(fā)現(xiàn)許多新的代碼編輯功能,具體內(nèi)容詳情跟隨小編看看有哪些新特性2020-12-12golang實(shí)現(xiàn)java uuid的序列化方法
這篇文章主要介紹了golang實(shí)現(xiàn)java uuid的序列化方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Golang?range?slice?與range?array?之間的區(qū)別
這篇文章主要介紹了Golang?range?slice?與range?array?之間的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07go語言區(qū)塊鏈實(shí)戰(zhàn)實(shí)現(xiàn)簡單的區(qū)塊與區(qū)塊鏈
這篇文章主要為大家介紹了go語言區(qū)塊鏈的實(shí)戰(zhàn)學(xué)習(xí),來實(shí)現(xiàn)簡單的區(qū)塊與區(qū)塊鏈?zhǔn)纠^程,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10