詳解golang中的結(jié)構(gòu)體編解碼神器Mapstructure庫(kù)
一:介紹
簡(jiǎn)言之: mapstructure是GO字典(map[string]interface{})和Go結(jié)構(gòu)體之間轉(zhuǎn)換的編解碼工具。
核心方法:mapstructure.Decode(input interface{}, output interface{})
二:安裝
go get github.com/mitchellh/mapstructure
源碼地址:https://github.com/mitchellh/mapstructure
官方文檔地址:https://pkg.go.dev/github.com/mitchellh/mapstructure
三:使用
3.1: 簡(jiǎn)單使用案例
案例:將一個(gè)JSON字符串解析為字典對(duì)象, 然后把字典綁定到一個(gè)結(jié)構(gòu)體對(duì)象中。
package main import ( "encoding/json" "fmt" "github.com/mitchellh/mapstructure" "log" ) type Person struct { Name string Age int Job string } func main() { // 定義一個(gè)JSON字符串 dataJson := `{ "name":"renshanwen", "age":18, "job": "engineer" }` // 將JOSN字符串解析成字典 var m map[string]interface{} err := json.Unmarshal([]byte(dataJson), &m) if err != nil { log.Fatal(err) } // 將結(jié)構(gòu)體m,綁定到結(jié)構(gòu)體對(duì)象p中 var p Person mapstructure.Decode(m, &p) fmt.Printf("name is %s, age is %d, job is %s.", p.Name, p.Age, p.Job) }
輸出結(jié)果:
name is renshanwen, age is 18, job is engineer.
3.2: 字段標(biāo)簽
字段標(biāo)簽作用:定義Go字典和GO結(jié)構(gòu)體字段映射關(guān)系。
默認(rèn):mapstructure使用結(jié)構(gòu)體中字段的名稱(大小寫(xiě)不敏感)做這個(gè)映射,
案例:例如我們的結(jié)構(gòu)體有一個(gè)Name字段,mapstructure解碼時(shí)會(huì)在map[string]interface{}中查找鍵名name。
指定關(guān)系映射:
package main import ( "encoding/json" "fmt" "github.com/mitchellh/mapstructure" "log" ) type Person struct { Name string `mapstructure:"user_name"` Age int `mapstructure:"user_age"` Job string `mapstructure:"user_job"` } func main() { // 定義一個(gè)JSON字符串 dataJson := `{ "user_name":"renshanwen", "user_age":18, "user_job": "engineer" }` // 將JOSN字符串解析成結(jié)構(gòu)體 var m map[string]interface{} err := json.Unmarshal([]byte(dataJson), &m) if err != nil { log.Fatal(err) } // 將結(jié)構(gòu)體m,綁定到結(jié)構(gòu)體對(duì)象p中 var p Person mapstructure.Decode(m, &p) fmt.Printf("name is %s, age is %d, job is %s.", p.Name, p.Age, p.Job) }
3.3: 結(jié)構(gòu)體嵌套
如果入?yún)SON結(jié)構(gòu)比較復(fù)雜, 可以定義多重結(jié)構(gòu)體, mapstructure會(huì)自動(dòng)幫助我們解析。
package main import ( "encoding/json" "fmt" "github.com/mitchellh/mapstructure" "log" ) type Person struct { Name string `mapstructure:"user_name"` Age int `mapstructure:"user_age"` Job string `mapstructure:"user_job"` } // Worker 結(jié)構(gòu)體嵌套 type Worker struct { Person Person Work string `mapstructure:"user_work"` } func main() { // 定義一個(gè)JSON字符串 dataJson := `{ "person":{ "user_name":"renshanwen", "user_age":18, "user_job":"engineer" }, "user_work":"code" }` // 將JOSN字符串解析成結(jié)構(gòu)體 var m map[string]interface{} err := json.Unmarshal([]byte(dataJson), &m) if err != nil { log.Fatal(err) } // 將結(jié)構(gòu)體m,綁定到結(jié)構(gòu)體對(duì)象w中 var w Worker mapstructure.Decode(m, &w) fmt.Printf("name is %s, age is %d, job is %s ,work is %s.", w.Person.Name, w.Person.Age, w.Person.Job, w.Work) }
3.4: 統(tǒng)一存儲(chǔ)未映射的值
可以定義一個(gè)字段,接收全部沒(méi)有映射的字段。
案例:
package main import ( "encoding/json" "fmt" "github.com/mitchellh/mapstructure" "log" ) type Person struct { Name string `mapstructure:"user_name"` Age int `mapstructure:"user_age"` Job string `mapstructure:"user_job"` } // Worker 結(jié)構(gòu)體嵌套 type Worker struct { Person Person Work string `mapstructure:"user_work"` Other map[string]interface{} `mapstructure:",remain"` // 未解析字段默認(rèn)分配到這里 } func main() { // 定義一個(gè)JSON字符串 dataJson := `{ "person":{ "user_name":"renshanwen", "user_age":18, "user_job":"engineer" }, "user_work":"code", "user_mather": "mather", "user_baby": "baby" }` // 將JOSN字符串解析成結(jié)構(gòu)體 var m map[string]interface{} err := json.Unmarshal([]byte(dataJson), &m) if err != nil { log.Fatal(err) } // 將結(jié)構(gòu)體m,綁定到結(jié)構(gòu)體對(duì)象w中 var w Worker mapstructure.Decode(m, &w) fmt.Printf("name is %s, age is %d, job is %s ,work is %s other is %s.", w.Person.Name, w.Person.Age, w.Person.Job, w.Work, w.Other) }
結(jié)果:
name is renshanwen, age is 18, job is engineer ,work is code other is map[user_baby:baby user_mather:mather].
3.5: 逆向轉(zhuǎn)換
結(jié)構(gòu)體—>字典
在反向解碼時(shí),我們可以為某些字段設(shè)置mapstructure:“,omitempty”。這樣當(dāng)這些字段為默認(rèn)值時(shí),就不會(huì)出現(xiàn)在結(jié)構(gòu)的map[string]interface{}。
package main import ( "encoding/json" "fmt" "github.com/mitchellh/mapstructure" ) type Person struct { Name string `mapstructure:"user_name"` Age int `mapstructure:"user_age"` Job string `mapstructure:"user_job,omitempty"` // ,omitempty表示如果結(jié)構(gòu)體對(duì)象沒(méi)有,則不會(huì)解析到字典中。 } // Worker 結(jié)構(gòu)體嵌套 type Worker struct { Person Person Work string `mapstructure:"user_work"` Other map[string]interface{} `mapstructure:",remain"` // 未解析字段默認(rèn)分配到這里 } func main() { // 定義一個(gè)JSON字符串 worker := &Worker{ Work: "code", } worker.Person.Name = "renshanwen" worker.Person.Age = 18 var m map[string]interface{} mapstructure.Decode(worker, &m) data, _ := json.Marshal(m) fmt.Println(string(data)) // {"Other":null,"Person":{"user_age":18,"user_name":"renshanwen"},"user_work":"code"} }
3.6: 收集綁定信息
可以使用mapstructure.Metadata, 存儲(chǔ)綁定信息情況。
Keys: 綁定成功的
Unused:沒(méi)有綁定上的
Unset:缺失的
package main import ( "fmt" "github.com/mitchellh/mapstructure" ) type Person struct { Name string `mapstructure:"user_name"` Age int `mapstructure:"user_age"` Job string `mapstructure:"user_job,omitempty"` // ,omitempty表示如果結(jié)構(gòu)體對(duì)象沒(méi)有,則不會(huì)解析到字典中。 } func main() { m := map[string]interface{}{ "user_name": "renshanwen", "age": 18, "job": "engineer", } var p Person var metadata mapstructure.Metadata mapstructure.DecodeMetadata(m, &p, &metadata) fmt.Printf("keys:%#v unused:%#v Unset:%#v \n", metadata.Keys, metadata.Unused, metadata.Unset) // keys:[]string{"user_name"} unused:[]string{"age", "job"} Unset:[]string{"user_age", "user_job"} }
以上就是詳解golang中的結(jié)構(gòu)體編解碼神器Mapstructure庫(kù)的詳細(xì)內(nèi)容,更多關(guān)于go Mapstructure的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
go語(yǔ)言異常panic和恢復(fù)recover用法實(shí)例
這篇文章主要介紹了go語(yǔ)言異常panic和恢復(fù)recover用法,實(shí)例分析了異常panic和恢復(fù)recover使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03使用Go語(yǔ)言創(chuàng)建WebSocket服務(wù)的實(shí)現(xiàn)示例
這篇文章主要介紹了使用Go語(yǔ)言創(chuàng)建WebSocket服務(wù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Go語(yǔ)言{}大括號(hào)的特殊用法實(shí)例探究
這篇文章主要為大家介紹了Go語(yǔ)言{}大括號(hào)的特殊用法實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01詳解在Go語(yǔ)言單元測(cè)試中如何解決Redis存儲(chǔ)依賴問(wèn)題
在編寫(xiě)單元測(cè)試時(shí),除了?MySQL?這個(gè)外部存儲(chǔ)依賴,Redis?應(yīng)該是另一個(gè)最為常見(jiàn)的外部存儲(chǔ)依賴了,本文就來(lái)講解下如何解決?Redis?外部依賴,文章通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08執(zhí)行g(shù)o?vendor第三方包版本沖突問(wèn)題解決
這篇文章主要為大家介紹了執(zhí)行g(shù)o?vendor時(shí),第三方包go版本沖突問(wèn)題的解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07