a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > Golang > 正文

Golang JSON的進(jìn)階用法實(shí)例講解

2020-04-01 18:52:59
字體:
供稿:網(wǎng)友

痛點(diǎn)

json 是當(dāng)前最常用的數(shù)據(jù)傳輸格式之一,純文本,容易使用,方便閱讀,在通信過程中大量被使用。 

你是否遇到過json中某個字段填入某種類型都適合而陷入兩難境地? (例如:定義了一個port字段,你卻不知道是填入 8080 ,還是 “8080” 的尷尬局面)

你是否遇到過json反解析報錯是因?yàn)樘钊胱侄蔚念愋筒黄ヅ鋵?dǎo)致的?例如:

json: cannot unmarshal number into Go struct field Host.port of type string

你是否有json某字段兼容2種或者多種的數(shù)據(jù)結(jié)構(gòu)的需求?

你是否想讓程序更優(yōu)雅,更具有適配性,而不在被這些小細(xì)節(jié)頭痛?

如果你有或者你想,獲取你可以看看這篇文章。

重現(xiàn)問題

我們給了用戶一個json如下:

{ "name":"yulibaozi", "port":8080}

但是,業(yè)務(wù)方卻誤填了”8080”,結(jié)果我們程序反解析報錯,導(dǎo)致業(yè)務(wù)失敗。

json: cannot unmarshal number into Go struct field Host.port of type string

或許你認(rèn)為這是業(yè)務(wù)方的問題,但我認(rèn)為我們可以更優(yōu)雅的解決這個問題。

如何解決問題

我們先定義了一個結(jié)構(gòu)體

type Host struct { Name string `json:"name"` Port Port `json:"port"`}

心細(xì)的你會發(fā)現(xiàn),Port既不是int也不是string類型,而是Port類型,而Port類型是:

type Type intconst ( Int Type = iota String)type Port struct { Type Type IntVal int StrVal string}

在Port結(jié)構(gòu)體中,我們發(fā)現(xiàn)了Type類型, 而Type類型包括了int,string兩種類型。接下來就非常重要了,我們需要實(shí)現(xiàn)以下這兩個接口。

json.Unmarshaller interfacejson.Marshaller interface

實(shí)現(xiàn)代碼如下:

type Port struct { Type Type IntVal int StrVal string}// 實(shí)現(xiàn) json.Unmarshaller 接口func (port *Port) UnmarshalJSON(value []byte) error { if value[0] == '"' {  port.Type = String  return json.Unmarshal(value, &port.StrVal) } port.Type = Int return json.Unmarshal(value, &port.IntVal)}// 實(shí)現(xiàn) json.Marshaller 接口func (port Port) MarshalJSON() ([]byte, error) { switch port.Type { case Int:  return json.Marshal(port.IntVal) case String:  return json.Marshal(port.StrVal) default:  return []byte{}, fmt.Errorf("impossible Port.Type") }}

接下來測試:

測試反解析

測試反解析int

給出json數(shù)據(jù):

{"name":"yulibaozi","port":8090}

反解析得到的結(jié)構(gòu)體數(shù)據(jù)如下:

&{Name:yulibaozi Port:{Type:0 IntVal:8090 StrVal:}}

測試反解析string:

給出json數(shù)據(jù):

{"name":"yulibaozi","port":"8090"}

反解析得到的結(jié)構(gòu)體數(shù)據(jù)如下:

&{Name:yulibaozi Port:{Type:1 IntVal:0 StrVal:8090}}

測試編碼的json

測試編碼int的結(jié)構(gòu)體如下:

host := &Host{   Name: "yulibaozi",   Port: Port{     Type:  Int,     IntVal: 8080,   }, }

編碼后的json如下:

{"name":"yulibaozi","port":8080}

測試編碼string的結(jié)構(gòu)體如下:

host := &Host{   Name: "yulibaozi",   Port: Port{     Type:  String,     StrVal: "8080",   }, }

編碼后的json數(shù)據(jù)如下:

{"name":"yulibaozi","port":"8080"}

在反編碼測試中,你會發(fā)現(xiàn)當(dāng)json填入的類型不同時,會編碼到結(jié)構(gòu)體中對應(yīng)的字段中。

在編碼測試中, 具體編碼那個數(shù)據(jù)是由Type來確定的。

總結(jié)

其實(shí),這篇文章只是分享了下json中使用的小技巧,他打破了在使用json時,需要呆板的數(shù)據(jù)結(jié)構(gòu)的印象,轉(zhuǎn)而走向了多變,靈活跳脫的風(fēng)格,其實(shí),這這個小tips的核心在于實(shí)現(xiàn)Unmarshaller,Marshaller這兩個結(jié)構(gòu)體,他們的實(shí)現(xiàn)是這個分享的關(guān)鍵,當(dāng)然,你可以實(shí)現(xiàn)如開篇所說的那樣,json某字段兼容2種及以上結(jié)構(gòu),當(dāng)然,你也可以對yaml,toml等進(jìn)行折騰,都會得到你想要的答案。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網(wǎng)的支持。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 免费黄在线观看 | 欧美成人免费视频 | 在线精品一区 | 亚洲精品一区二三区不卡 | 日韩视频一区 | 色呦呦在线视频 | 精品久久久久久久久久久久久久 | 欧美成人黑人xx视频免费观看 | 欧美不卡激情三级在线观看 | 国产精品色网站 | 国内精品国产成人国产三级粉色 | jjzz日本| 国产精品亚洲一区 | 一区免费视频 | 国产91精品一区二区绿帽 | 91视频污黄 | 成人在线一区二区 | 毛片链接 | 欧美日韩福利视频 | 亚洲中字幕 | 久久ri资源网 | 亚洲电影在线看 | 国产日韩欧美一区二区 | 91精品一区二区三区久久久久 | av在线一区二区 | 羞羞视频网站 | 操操操操网 | 羞羞视频网站在线观看 | 精品免费视频 | 一级国产视频 | 国产亚洲欧美在线 | 成人特级毛片 | 国精日本亚洲欧州国产中文久久 | 久草在线观看福利视频 | 在线日韩精品视频 | 久草天堂 | 久久精品99国产精品日本 | 三级精品 | 日韩视频在线观看中文字幕 | 成人在线中文字幕 | 欧美一区2区三区4区公司二百 |