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