濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > Golang JSON的進(jìn)階用法實(shí)例講解

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

熱門標(biāo)簽:濱州自動(dòng)電銷機(jī)器人排名 浙江高頻外呼系統(tǒng)多少錢一個(gè)月 惠州電銷防封電話卡 黃岡人工智能電銷機(jī)器人哪個(gè)好 汕頭小型外呼系統(tǒng) 釘釘有地圖標(biāo)注功能嗎 鄭州亮點(diǎn)科技用的什么外呼系統(tǒng) 建造者2地圖標(biāo)注 阿里云ai電話機(jī)器人

痛點(diǎn)

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

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

你是否遇到過(guò)json反解析報(bào)錯(cuò)是因?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)問(wèn)題

我們給了用戶一個(gè)json如下:

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

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

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

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

如何解決問(wèn)題

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

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

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

type Type int

const (
 Int Type = iota
 String
)

type Port struct {
 Type Type
 IntVal int
 StrVal string
}

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

json.Unmarshaller interface
json.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")
 }
}

接下來(lái)測(cè)試:

測(cè)試反解析

測(cè)試反解析int

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

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

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

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

測(cè)試反解析string:

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

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

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

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

測(cè)試編碼的json

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

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

編碼后的json如下:

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

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

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

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

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

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

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

總結(jié)

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

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

您可能感興趣的文章:
  • golang使用json格式實(shí)現(xiàn)增刪查改的實(shí)現(xiàn)示例
  • golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法
  • golang結(jié)構(gòu)體與json格式串實(shí)例代碼
  • golang如何修改json文件內(nèi)容的方法示例
  • golang如何自定義json序列化應(yīng)用詳解
  • golang json性能分析詳解
  • golang中json反序列化可能遇到的問(wèn)題
  • Golang map如何生成有序的json數(shù)據(jù)詳解
  • 利用Golang解析json數(shù)據(jù)的方法示例
  • Golang中使用JSON的一些小技巧分享
  • golang實(shí)現(xiàn)sql結(jié)果集以json格式輸出的方法
  • Golang 如何解析和生成json

標(biāo)簽:昭通 東營(yíng) 泰安 駐馬店 瀘州 阿壩 晉中 滄州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Golang JSON的進(jìn)階用法實(shí)例講解》,本文關(guān)鍵詞  Golang,JSON,的,進(jìn)階,用法,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Golang JSON的進(jìn)階用法實(shí)例講解》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Golang JSON的進(jìn)階用法實(shí)例講解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    太仓市| 盐亭县| 湖州市| 汨罗市| 汝南县| 桃源县| 武陟县| 罗山县| 新晃| 冕宁县| 商都县| 江川县| 屏南县| 二手房| 长沙市| 安宁市| 平谷区| 德安县| 博白县| 阜康市| 商城县| 南木林县| 偃师市| 平武县| 湾仔区| 正镶白旗| 吴川市| 凭祥市| 蒙阴县| 泰顺县| 凉山| 察隅县| 新源县| 甘泉县| 安乡县| 精河县| 易门县| 闽清县| 鹤壁市| 错那县| 务川|