一文帶你了解Go語言如何解析JSON
JSON 解析為結(jié)構(gòu)體
JSON 的結(jié)構(gòu)是 key-value,最直觀的就是將 JSON 解析為結(jié)構(gòu)體,如下 JSON :
{
"name": yuzhou1u,
"age": 18
}Go 語言中,提供了一個(gè)專門的包 encoding/json ,所以我們在使用這個(gè) JSON 包之前需要在頭文件導(dǎo)入:
package main import ( "encoding/json" "fmt" )
然后,我們需要定義一個(gè) Go 語言的結(jié)構(gòu)體以便我們能與 JSON 一一對應(yīng),比如在 JSON 中我們定義了姓名 name 和年齡 age ,所以需要定義一個(gè)結(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ù)的代碼:
- 定義一個(gè) Person 的 p 對象
- 因?yàn)槲覀儧]有把文件系統(tǒng)使用上,所以是定義了一個(gè)
jsonString的 JSON 數(shù)據(jù) - 使用
json.Unmarshal()函數(shù)能夠解析 JSON 格式的數(shù)據(jù)。但需要將 JSON 字符串轉(zhuǎn)換為字節(jié)切片,并將結(jié)果存儲到 p 對象中。 使用需要使用 & 地址運(yùn)算符傳入人員的地址。 - 如果解析有效,則
json.Unmarshal()函數(shù)返回 nil,您現(xiàn)在可以找到存儲在 person 變量中的值。 - 確保將 Person 結(jié)構(gòu)中每個(gè)字段的第一個(gè)字符大寫。 如果字段名稱以小寫字母開頭,則不會導(dǎo)出到當(dāng)前包之外,并且字段對
json.Unmarshal()函數(shù)不可見。
運(yùn)行上述代碼,打印在控制臺中結(jié)果為:
yuzhou1su
18
JSON 解析為數(shù)組
通常 JSON 數(shù)據(jù)會包括一系列的對象數(shù)組,就像這樣一個(gè)班級的數(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 嵌入對象
JSON 字符串有時(shí)包含嵌入對象,比如:
{
"name": "yuzhou1su",
"age": 18,
"address": {
"road": "renmin south road",
"street": "123 street",
"city": "cs",
"province": "hn",
"country": "cn"
}
}address 就是屬于內(nèi)嵌對象,我們同樣需要創(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"
}請注意,此 JSON 字符串中的鍵中有空格。 如果你嘗試將它直接映射到一個(gè)結(jié)構(gòu),你會遇到問題,因?yàn)?Go 中的變量名不能有空格。 要解決此問題,您可以使用結(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é)展示了相對簡單的 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{}上面的語句創(chuàng)建了一個(gè) map 類型的變量 result,它的 key 是 string 類型,每個(gè)對應(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ù)格式,有著非常多的使用場景。本篇文章介紹了如何利用 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)文章希望大家以后多多支持腳本之家!
- Go與Rust高性能解析JSON實(shí)現(xiàn)方法示例
- golang解析json數(shù)據(jù)的4種方法總結(jié)
- Golang解析JSON遇到的坑及解決方法
- Go語言學(xué)習(xí)之JSON編碼解析與使用
- Go語言實(shí)現(xiàn)JSON解析的神器詳解
- Go語言JSON解析器gjson使用方法詳解
- Golang實(shí)現(xiàn)解析JSON的三種方法總結(jié)
- golang生成JSON以及解析JSON
- Go?語言?json解析框架與?gjson?詳解
- go語言用八百行代碼實(shí)現(xiàn)一個(gè)JSON解析器
- Go語言實(shí)現(xiàn)JSON解析的方法詳解
- GO中Json解析的幾種方式
相關(guān)文章
Go語言實(shí)現(xiàn)AzDG可逆加密算法實(shí)例
這篇文章主要介紹了Go語言實(shí)現(xiàn)AzDG可逆加密算法,實(shí)例分析了AzDG可逆加密算法的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
詳解Go語言中如何通過Goroutine實(shí)現(xiàn)高并發(fā)
在Go語言中,并發(fā)編程是一個(gè)核心且強(qiáng)大的特性,Go語言通過goroutine和channel等機(jī)制,使得并發(fā)編程變得更加簡單和直觀,本文給大家介紹了Go語言中如何通過Goroutine快速實(shí)現(xiàn)高并發(fā),感興趣的小伙伴跟著小編一起來看看吧2024-10-10
vscode上搭建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-10
golang將切片或數(shù)組根據(jù)某個(gè)字段進(jìn)行分組操作
這篇文章主要介紹了golang將切片或數(shù)組根據(jù)某個(gè)字段進(jìn)行分組操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
Go內(nèi)存節(jié)省技巧簡單實(shí)現(xiàn)方法
這篇文章主要為大家介紹了Go內(nèi)存節(jié)省技巧簡單實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Golang使用pprof和trace進(jìn)行診斷和修復(fù)性能問題
在?Go?中,開發(fā)人員可以使用強(qiáng)大的內(nèi)置工具來幫助診斷和修復(fù)性能問題,其中兩個(gè)工具是?pprof?和?trace?包,下面就跟隨小編一起來了解下如何使用pprof和trace進(jìn)行診斷和修復(fù)性能問題吧2024-01-01

