国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Golang > 正文

Golang JSON的進階用法實例講解

2020-04-01 18:52:59
字體:
來源:轉載
供稿:網友

痛點

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

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

你是否遇到過json反解析報錯是因為填入字段的類型不匹配導致的?例如:

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

你是否有json某字段兼容2種或者多種的數據結構的需求?

你是否想讓程序更優雅,更具有適配性,而不在被這些小細節頭痛?

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

重現問題

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

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

但是,業務方卻誤填了”8080”,結果我們程序反解析報錯,導致業務失敗。

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

或許你認為這是業務方的問題,但我認為我們可以更優雅的解決這個問題。

如何解決問題

我們先定義了一個結構體

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

心細的你會發現,Port既不是int也不是string類型,而是Port類型,而Port類型是:

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

在Port結構體中,我們發現了Type類型, 而Type類型包括了int,string兩種類型。接下來就非常重要了,我們需要實現以下這兩個接口。

json.Unmarshaller interfacejson.Marshaller interface

實現代碼如下:

type Port struct { Type Type IntVal int StrVal string}// 實現 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)}// 實現 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數據:

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

反解析得到的結構體數據如下:

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

測試反解析string:

給出json數據:

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

反解析得到的結構體數據如下:

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

測試編碼的json

測試編碼int的結構體如下:

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

編碼后的json如下:

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

測試編碼string的結構體如下:

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

編碼后的json數據如下:

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

在反編碼測試中,你會發現當json填入的類型不同時,會編碼到結構體中對應的字段中。

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

總結

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

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 上栗县| 南皮县| 鞍山市| 当涂县| 青岛市| 泸西县| 常州市| 兰考县| 上饶县| 伊吾县| 沁阳市| 望谟县| 汾西县| 嘉定区| 马龙县| 灵武市| 利川市| 邵东县| 石狮市| 乌鲁木齐县| 博客| 临夏县| 安塞县| 钦州市| 林西县| 德阳市| 铁岭县| 水城县| 张北县| 嘉黎县| 海原县| 邯郸市| 水富县| 庆阳市| 太谷县| 社会| 鲁甸县| 尚志市| 康定县| 淮安市| 吴忠市|