詳解Go語言中結(jié)構(gòu)體與JSON間的轉(zhuǎn)換
前言
在日常開發(fā)中,我們往往會將 JSON 解析成對應(yīng)的結(jié)構(gòu)體,反之也會將結(jié)構(gòu)體轉(zhuǎn)成 JSON。接下來本文會通過 JSON 包的兩個函數(shù),來介紹 JSON 與結(jié)構(gòu)體之間的轉(zhuǎn)換。
結(jié)構(gòu)體轉(zhuǎn) JSON
Marshal(v any) ([]byte, error):將 v 轉(zhuǎn)成 JSON 數(shù)據(jù),以 []byte 的形式返回。
import (
"encoding/json"
"fmt"
)
type User struct {
Name string
Age int
Height float64
Weight *float64
Child bool
marriageStatus string
}
func main() {
weight := 120.5
user := User{
Name: "gopher",
Age: 18,
Height: 180.5,
Weight: &weight,
Child: false,
marriageStatus: "未婚",
}
jsonBytes, err := json.Marshal(user)
if err != nil {
fmt.Println("error: ", err)
return
}
fmt.Println(string(jsonBytes)) // {"Name":"gopher","Age":18,"Height":180.5,"Weight":120.5,"Child":false}
}
執(zhí)行結(jié)果:
{"Name":"gopher","Age":18,"Height":180.5,"Weight":120.5,"Child":false}
根據(jù)結(jié)果可知:
- 不可導(dǎo)出字段(字段名以小寫字母開頭),是不能被轉(zhuǎn)成
JSON的key的,這也符合Go的語法規(guī)定,以小寫字母開頭的變量或結(jié)構(gòu)體字段等,不能在包外被訪問。 - 轉(zhuǎn)換后的字段名,與結(jié)構(gòu)體字段的名字一樣。
- 如果字段是指針類型,轉(zhuǎn)換后的值為指針指向的字段值。
如果我們想要指定字段轉(zhuǎn)換之后的命名,或者將一個可導(dǎo)出的字段進(jìn)行忽略,可以通過給結(jié)構(gòu)體字段打上 JSON 標(biāo)簽的方式實現(xiàn)。
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Height float64 `json:"height"`
Weight *float64 `json:"weight"`
Child bool `json:"child"`
MarriageStatus string `json:"-"`
}
func main() {
weight := 120.5
user := User{
Name: "gopher",
Age: 18,
Height: 180.5,
Weight: &weight,
Child: false,
MarriageStatus: "未婚",
}
jsonBytes, err := json.Marshal(user)
if err != nil {
fmt.Println("error: ", err)
return
}
fmt.Println(string(jsonBytes)) // {"name":"gopher","age":18,"height":180.5,"weight":120.5,"child":false}
}通過給結(jié)構(gòu)體字段定打上 JSON 標(biāo)簽,可指定轉(zhuǎn)成 JSON 后的字段名,如果 JSON 標(biāo)簽的值為 -,則在轉(zhuǎn)換 JSON 時忽略此字段。
JSON 解析結(jié)構(gòu)體
Unmarshal(data []byte, v any) error:將 JSON 解析成指定的結(jié)構(gòu)體。
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Height float64 `json:"height"`
Child bool `json:"-"`
marriageStatus string
}
func main() {
userStr := `
{
"name": "gopher",
"age": 18,
"height": 180.5,
"child": true,
"marriageStatus": "未婚"
}
`
user := &User{}
err := json.Unmarshal([]byte(userStr), &user)
if err != nil {
fmt.Println("error: ", err)
return
}
fmt.Printf("%#v", user) // &main.User{Name:"gopher", Age:18, Height:180.5, Child:false, marriageStatus:""}
}執(zhí)行結(jié)果:
&main.User{Name:"gopher", Age:18, Height:180.5, Child:false, marriageStatus:""}
根據(jù)結(jié)果可知:
使用Unmarshal函數(shù)時,我們需要傳入結(jié)構(gòu)體的指針類型,否則結(jié)構(gòu)體字段的值將不會被改變,因為底層是通過指針去修改結(jié)構(gòu)體字段的值。
JSON 解析時,JSON 的 key 與結(jié)構(gòu)體字段的匹配規(guī)則是:
- 優(yōu)先查找
JSON標(biāo)簽值和key一樣的,找到則將value賦值給對應(yīng)字段。 - 如果沒有
JSON標(biāo)簽值與key相匹配,則根據(jù)字段名進(jìn)行匹配。
可以發(fā)現(xiàn),如果結(jié)構(gòu)體字段是非導(dǎo)出字段或 JSON 標(biāo)簽的值為 -,將不會被匹配到。
小結(jié)
本文介紹了 Go 語言里,JSON 與結(jié)構(gòu)體之間的轉(zhuǎn)換。在結(jié)構(gòu)體轉(zhuǎn) JSON 時,我們可以通過給字段打標(biāo)簽,指定轉(zhuǎn)換后的 key 命名,需要注意的是,如果結(jié)構(gòu)體的字段為非導(dǎo)出字段或字段的 JSON 標(biāo)簽值為 -,在轉(zhuǎn)換 JSON 時,將會被忽略。反之 JSON 解析結(jié)構(gòu)體時也是一樣的。
到此這篇關(guān)于詳解Go語言中結(jié)構(gòu)體與JSON間的轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Go語言結(jié)構(gòu)體 JSON內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從淺入深帶你掌握Golang數(shù)據(jù)結(jié)構(gòu)map
在?Go?語言中,map?是一種非常常見的數(shù)據(jù)類型,它可以用于快速地檢索數(shù)據(jù)。本篇文章將介紹?Go?語言中的?map,包括?map?的定義、初始化、操作和優(yōu)化,需要的可以參考一下2023-04-04
go語言阻塞函數(shù)和非阻塞函數(shù)實現(xiàn)
本文主要介紹了go語言阻塞函數(shù)和非阻塞函數(shù)實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
Golang創(chuàng)建構(gòu)造函數(shù)的方法超詳細(xì)講解
構(gòu)造器一般面向?qū)ο笳Z言的典型特性,用于初始化變量。Go語言沒有任何具體構(gòu)造器,但我們能使用該特性去初始化變量。本文介紹不同類型構(gòu)造器的差異及其應(yīng)用場景2023-01-01

