一文帶你了解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è)專門的包 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è)字符大寫。 如果字段名稱以小寫字母開頭,則不會(huì)導(dǎo)出到當(dāng)前包之外,并且字段對(duì)
json.Unmarshal()函數(shù)不可見。
運(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
自定義屬性名稱的映射
有時(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 類型的變量 result,它的 key 是 string 類型,每個(gè)對(duì)應(yīng)的 value 都是 interface{} 類型。 這個(gè)空接口表示該值可以是任何類型:
為了解析這個(gè) JSON 字符串,我們應(yīng)該使用 json.Unmarshal() 函數(shù):
json.Unmarshal([]byte(jsonString), &result)
因?yàn)?result 的類型是接口,所有可以傳入任何類型:
- 當(dāng)解析 success 鍵的話可以使用
result["sucess"],解析為布爾型。 - 當(dāng)解析
timestamp時(shí)可以解析為數(shù)字類型 - 解析 rates 使用傳入
rates即可, 即rates := result["rates"],解析為 map 類型
整個(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ù)作為常見的數(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)文章
Golang使用Decimal庫(kù)避免運(yùn)算中精度損失詳細(xì)步驟
decimal是為了解決Golang中浮點(diǎn)數(shù)計(jì)算時(shí)精度丟失問(wèn)題而生的一個(gè)庫(kù),使用decimal庫(kù)我們可以避免在go中使用浮點(diǎn)數(shù)出現(xiàn)精度丟失的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Golang使用Decimal庫(kù)避免運(yùn)算中精度損失的相關(guān)資料,需要的朋友可以參考下2023-06-06
Golang發(fā)送http GET請(qǐng)求的示例代碼
這篇文章主要介紹了Golang發(fā)送http GET請(qǐng)求的示例代碼,幫助大家更好的理解和使用golang,感興趣的朋友可以了解下2020-12-12
Go語(yǔ)言實(shí)戰(zhàn)之實(shí)現(xiàn)均衡器功能
這篇文章主要為大家詳細(xì)介紹了如何利用Golang?實(shí)現(xiàn)一個(gè)簡(jiǎn)單的流浪均衡器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-04-04

