一文帶你了解Go語(yǔ)言如何解析JSON
JSON 解析為結(jié)構(gòu)體
JSON 的結(jié)構(gòu)是 key-value,最直觀的就是將 JSON 解析為結(jié)構(gòu)體,如下 JSON :
{ "name": yuzhou1u, "age": 18 }
Go 語(yǔ)言中,提供了一個(gè)專(zhuān)門(mén)的包 encoding/json
,所以我們?cè)谑褂眠@個(gè) JSON 包之前需要在頭文件導(dǎo)入:
package main import ( "encoding/json" "fmt" )
然后,我們需要定義一個(gè) Go 語(yǔ)言的結(jié)構(gòu)體以便我們能與 JSON 一一對(duì)應(yīng),比如在 JSON 中我們定義了姓名 name
和年齡 age
,所以需要定義一個(gè)結(jié)構(gòu)體(命名可以隨意,但最好通俗易懂)的字段與 JSON 字符串中的鍵相匹配:
type Person struct { Name string Age int }
然后使用 json.Umarshal()
函數(shù)來(lái)解析 JSON 字符串,完整代碼如下:
package main import ( "encoding/json" "fmt" ) type Person struct { Name string Age int } func main() { var p Person jsonString := `{"name": "yuzhou1su", "age" : 18}` err := json.Unmarshal([]byte(jsonString), &p) if err == nil { fmt.Println(p.Name) fmt.Println(p.Age) } else { fmt.Println(err) } }
現(xiàn)在來(lái)解釋一下上面 main 函數(shù)的代碼:
- 定義一個(gè) Person 的 p 對(duì)象
- 因?yàn)槲覀儧](méi)有把文件系統(tǒng)使用上,所以是定義了一個(gè)
jsonString
的 JSON 數(shù)據(jù) - 使用
json.Unmarshal()
函數(shù)能夠解析 JSON 格式的數(shù)據(jù)。但需要將 JSON 字符串轉(zhuǎn)換為字節(jié)切片,并將結(jié)果存儲(chǔ)到 p 對(duì)象中。 使用需要使用 & 地址運(yùn)算符傳入人員的地址。 - 如果解析有效,則
json.Unmarshal()
函數(shù)返回 nil,您現(xiàn)在可以找到存儲(chǔ)在 person 變量中的值。 - 確保將 Person 結(jié)構(gòu)中每個(gè)字段的第一個(gè)字符大寫(xiě)。 如果字段名稱(chēng)以小寫(xiě)字母開(kāi)頭,則不會(huì)導(dǎo)出到當(dāng)前包之外,并且字段對(duì)
json.Unmarshal()
函數(shù)不可見(jiàn)。
運(yùn)行上述代碼,打印在控制臺(tái)中結(jié)果為:
yuzhou1su
18
JSON 解析為數(shù)組
通常 JSON 數(shù)據(jù)會(huì)包括一系列的對(duì)象數(shù)組,就像這樣一個(gè)班級(jí)的數(shù)據(jù):
[ { "id": 1, "name": "張三" "age": 20 }, { "id": 2, "name": "李翠花" "age": 18 }, { "id": 3, "name": "王老五" "age": 25 } ]
我們只需要定義一個(gè) students[]
的數(shù)組,代碼如下:
package main import ( "encoding/json" "fmt" ) type Student struct { Id int Name string Age int } func main() { var students []Student myClass := `[ { "id": 1, "name": "張三", "age": 20 }, { "id": 2, "name": "李翠花", "age": 18 }, { "id": 3, "name": "王老五", "age": 25 } ]` err := json.Unmarshal([]byte(myClass), &students) if err == nil { for _, student := range students { fmt.Print("\t\n", student.Id) fmt.Print("\t", student.Name) fmt.Print("\t", student.Age) } } else { fmt.Println(err) } }
使用 for...range
迭代數(shù)組,然后運(yùn)行上述代碼:
$ go run main.go
1 張三 20
2 李翠花 18
3 王老五 25
解析 JSON 嵌入對(duì)象
JSON 字符串有時(shí)包含嵌入對(duì)象,比如:
{ "name": "yuzhou1su", "age": 18, "address": { "road": "renmin south road", "street": "123 street", "city": "cs", "province": "hn", "country": "cn" } }
address
就是屬于內(nèi)嵌對(duì)象,我們同樣需要?jiǎng)?chuàng)建另一個(gè) Address
結(jié)構(gòu)體:
package main import ( "encoding/json" "fmt" ) type Person struct { Name string Age int Address struct { Road string Street string City string Province string Country string } } func main() { var p Person jsonString := ` { "name": "yuzhou1su", "age": 18, "address": { "road": "renmin south road", "street": "123 street", "city": "cs", "province": "hn", "country": "cn" } }` err := json.Unmarshal([]byte(jsonString), &p) if err == nil { fmt.Println(p.Name) fmt.Println(p.Age) fmt.Println(p.Address.Road) fmt.Println(p.Address.Street) fmt.Println(p.Address.City) fmt.Println(p.Address.Province) fmt.Println(p.Address.Country) } else { fmt.Println(err) } }
輸出結(jié)果:
yuzhou1su
18
renmin south road
123 street
cs
hn
cn
自定義屬性名稱(chēng)的映射
有時(shí) JSON 字符串中的鍵不能直接映射到 Go 中結(jié)構(gòu)的成員。 比如:
{ "base currency": "USD", "destination currency": "CNY" }
請(qǐng)注意,此 JSON 字符串中的鍵中有空格。 如果你嘗試將它直接映射到一個(gè)結(jié)構(gòu),你會(huì)遇到問(wèn)題,因?yàn)?Go 中的變量名不能有空格。 要解決此問(wèn)題,您可以使用結(jié)構(gòu)字段標(biāo)記(在結(jié)構(gòu)中的每個(gè)字段之后放置的字符串文字),如下所示:
type Rates stuct { Base string `json:"base currency"` Symbol string `json:"destination currency"` }
- JSON 的
base currency
映射到 Go 中的Base
字段 - JSON 的
destination currency
映射到 Go 中Symbol
整合如下:
package main import ( "encoding/json" "fmt" ) type Rates struct { Base string `json:"base currency"` Symbol string `json:"destination currency"` } func main() { jsonString := ` { "base currency": "USD", "destination currency": "CNY" }` var rates Rates err := json.Unmarshal([]byte(jsonString), &rates) if err == nil { fmt.Println(rates.Base) fmt.Println(rates.Symbol) } else { fmt.Println(err) } }
運(yùn)行如下代碼:
$ go run main.go
USD
CNY
非結(jié)構(gòu)化數(shù)據(jù)的映射
前面幾節(jié)展示了相對(duì)簡(jiǎn)單的 JSON 字符串。 然而,在現(xiàn)實(shí)世界中,您要操作的 JSON 字符串通常很大且非結(jié)構(gòu)化。 此外,您可能只需要從 JSON 字符串中檢索特定值。
考慮以下 JSON 字符串:
{ "success": true, "timestamp": 1588779306, "base": "USD", "date": "2022-01-15", "rates": { "BNB": 0.00225, "BTC": 0.000020, "EUR": 0.879, "GBP": 0.733, "CNY": 6.36 } }
如果我們還想把美元解析為其他幣種,不至于重新定義整個(gè)結(jié)構(gòu)體,可以采取定義一個(gè)接口:
var result map[string] interface{}
上面的語(yǔ)句創(chuàng)建了一個(gè) map 類(lèi)型的變量 result,它的 key 是 string 類(lèi)型,每個(gè)對(duì)應(yīng)的 value 都是 interface{} 類(lèi)型。 這個(gè)空接口表示該值可以是任何類(lèi)型:
為了解析這個(gè) JSON 字符串,我們應(yīng)該使用 json.Unmarshal()
函數(shù):
json.Unmarshal([]byte(jsonString), &result)
因?yàn)?result 的類(lèi)型是接口,所有可以傳入任何類(lèi)型:
- 當(dāng)解析 success 鍵的話可以使用
result["sucess"]
,解析為布爾型。 - 當(dāng)解析
timestamp
時(shí)可以解析為數(shù)字類(lèi)型 - 解析 rates 使用傳入
rates
即可, 即rates := result["rates"]
,解析為 map 類(lèi)型
整個(gè)代碼如下:
package main import ( "encoding/json" "fmt" ) type Rates struct { Base string `json:"base currency"` Symbol string `json:"destination currency"` } func main() { jsonString := ` { "success": true, "timestamp": 1588779306, "base": "USD", "date": "2022-01-15", "rates": { "BNB": 0.00225, "BTC": 0.000020, "EUR": 0.879, "GBP": 0.733, "CNY": 6.36 } }` var result map[string]interface{} err := json.Unmarshal([]byte(jsonString), &result) if err == nil { fmt.Println(result["success"]) rates := result["rates"] fmt.Println(rates) } else { fmt.Println(err) } }
運(yùn)行代碼如下:
$ go run main.go
true
map[BNB:0.00225 BTC:2e-05 CNY:6.36 EUR:0.879 GBP:0.733]
總結(jié)
JSON 數(shù)據(jù)作為常見(jiàn)的數(shù)據(jù)格式,有著非常多的使用場(chǎng)景。本篇文章介紹了如何利用 Go 語(yǔ)言來(lái)解析 JSON 數(shù)據(jù),如解析為結(jié)構(gòu)體、數(shù)組、嵌入對(duì)象,解析自定義字段和解析非結(jié)構(gòu)化數(shù)據(jù)。
到此這篇關(guān)于一文帶你了解Go語(yǔ)言如何解析JSON的文章就介紹到這了,更多相關(guān)Go語(yǔ)言解析JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Go與Rust高性能解析JSON實(shí)現(xiàn)方法示例
- golang解析json數(shù)據(jù)的4種方法總結(jié)
- Golang解析JSON遇到的坑及解決方法
- Go語(yǔ)言學(xué)習(xí)之JSON編碼解析與使用
- Go語(yǔ)言實(shí)現(xiàn)JSON解析的神器詳解
- Go語(yǔ)言JSON解析器gjson使用方法詳解
- Golang實(shí)現(xiàn)解析JSON的三種方法總結(jié)
- golang生成JSON以及解析JSON
- Go?語(yǔ)言?json解析框架與?gjson?詳解
- go語(yǔ)言用八百行代碼實(shí)現(xiàn)一個(gè)JSON解析器
- Go語(yǔ)言實(shí)現(xiàn)JSON解析的方法詳解
- GO中Json解析的幾種方式
相關(guān)文章
Go語(yǔ)言實(shí)現(xiàn)AzDG可逆加密算法實(shí)例
這篇文章主要介紹了Go語(yǔ)言實(shí)現(xiàn)AzDG可逆加密算法,實(shí)例分析了AzDG可逆加密算法的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02詳解Go語(yǔ)言中如何通過(guò)Goroutine實(shí)現(xiàn)高并發(fā)
在Go語(yǔ)言中,并發(fā)編程是一個(gè)核心且強(qiáng)大的特性,Go語(yǔ)言通過(guò)goroutine和channel等機(jī)制,使得并發(fā)編程變得更加簡(jiǎn)單和直觀,本文給大家介紹了Go語(yǔ)言中如何通過(guò)Goroutine快速實(shí)現(xiàn)高并發(fā),感興趣的小伙伴跟著小編一起來(lái)看看吧2024-10-10vscode上搭建go開(kāi)發(fā)環(huán)境詳細(xì)完整過(guò)程
這篇文章主要給大家介紹了關(guān)于vscode上搭建go開(kāi)發(fā)環(huán)境的詳細(xì)完整過(guò)程,Go語(yǔ)言或?qū)⒊蔀樾碌闹髁﹂_(kāi)發(fā)語(yǔ)言,Go是google開(kāi)發(fā)的一種靜態(tài)強(qiáng)類(lèi)型、編譯型、并發(fā)型,并具有垃圾回收功能的編程語(yǔ)言,所以我們有必要學(xué)習(xí)并掌握它,需要的朋友可以參考下2023-10-10golang將切片或數(shù)組根據(jù)某個(gè)字段進(jìn)行分組操作
這篇文章主要介紹了golang將切片或數(shù)組根據(jù)某個(gè)字段進(jìn)行分組操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Go內(nèi)存節(jié)省技巧簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要為大家介紹了Go內(nèi)存節(jié)省技巧簡(jiǎn)單實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Golang使用pprof和trace進(jìn)行診斷和修復(fù)性能問(wèn)題
在?Go?中,開(kāi)發(fā)人員可以使用強(qiáng)大的內(nèi)置工具來(lái)幫助診斷和修復(fù)性能問(wèn)題,其中兩個(gè)工具是?pprof?和?trace?包,下面就跟隨小編一起來(lái)了解下如何使用pprof和trace進(jìn)行診斷和修復(fù)性能問(wèn)題吧2024-01-01