欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2018年09月26日 10:49:55   作者:yulibaozi  
這篇文章主要給大家介紹了關(guān)于Golang JSON進(jìn)階用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

痛點(diǎn)

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

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

你是否遇到過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)問題

我們給了用戶一個(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ù)方的問題,但我認(rèn)為我們可以更優(yōu)雅的解決這個(gè)問題。

如何解決問題

我們先定義了一個(gè)結(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 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兩種類型。接下來就非常重要了,我們需要實(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")
 }
}

接下來測試:

測試反解析

測試反解析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填入的類型不同時(shí),會編碼到結(jié)構(gòu)體中對應(yīng)的字段中。

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

總結(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)如開篇所說的那樣,json某字段兼容2種及以上結(jié)構(gòu),當(dāng)然,你也可以對yaml,toml等進(jìn)行折騰,都會得到你想要的答案。

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

相關(guān)文章

  • Go語言驅(qū)動(dòng)低代碼應(yīng)用引擎工具Yao開發(fā)管理系統(tǒng)

    Go語言驅(qū)動(dòng)低代碼應(yīng)用引擎工具Yao開發(fā)管理系統(tǒng)

    這篇文章主要為大家介紹了Go語言驅(qū)動(dòng)低代碼應(yīng)用引擎工具Yao開發(fā)管理系統(tǒng)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用教程

    Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用教程

    輸入輸出在任何一門語言中都必須提供的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Golang中空的切片轉(zhuǎn)化成 JSON 后變?yōu)?nbsp;null 問題的解決方案

    Golang中空的切片轉(zhuǎn)化成 JSON 后變?yōu)?nbsp;null 問題的解決方案

    在 Golang 中,經(jīng)常需要將其他類型(例如 slice、map、struct 等類型)的數(shù)據(jù)轉(zhuǎn)化為 JSON 格式,有時(shí)候轉(zhuǎn)化的結(jié)果并不是預(yù)期中的,例如將一個(gè)空的切片轉(zhuǎn)化為 JSON 時(shí),會變成"null",所以本文將給大家介紹一下解決方法,需要的朋友可以參考下
    2023-09-09
  • Go語言的GOPATH與工作目錄詳解

    Go語言的GOPATH與工作目錄詳解

    這篇文章主要介紹了Go語言的GOPATH與工作目錄詳解,本文詳細(xì)講解了GOPATH設(shè)置、應(yīng)用目錄結(jié)構(gòu)、編譯應(yīng)用等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • 深入理解Golang中指針的用途與技巧

    深入理解Golang中指針的用途與技巧

    在 Go 語言中,指針是一種重要的概念,了解和正確使用指非常關(guān)鍵,因此本文小編就來和大家講講Golang 中指針的概念與用法,希望對大家有所幫助
    2023-05-05
  • Go語言通道之無緩沖通道與緩沖通道詳解

    Go語言通道之無緩沖通道與緩沖通道詳解

    通道是一種特殊的數(shù)據(jù)結(jié)構(gòu),可以在協(xié)程之間進(jìn)行傳遞數(shù)據(jù),從而實(shí)現(xiàn)協(xié)程之間的通信和同步,本文就來和大家講講Go語言通道中的無緩沖通道與緩沖通道吧
    2023-06-06
  • 通過示例深度理解Go channel range

    通過示例深度理解Go channel range

    這篇文章主要為大家介紹了Go channel range使用示例深度理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Beego AutoRouter工作原理解析

    Beego AutoRouter工作原理解析

    這篇文章主要為大家介紹了Beego AutoRouter工作原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • golang值接收者和指針接收者的區(qū)別介紹

    golang值接收者和指針接收者的區(qū)別介紹

    這篇文章主要介紹了golang值接收者和指針接收者的區(qū)別,它和函數(shù)的區(qū)別在于方法有一個(gè)接收者,給一個(gè)函數(shù)添加一個(gè)接收者,那么它就變成了方法,接收者可以是值接收者,也可以是指針接收者,本文通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • golang interface判斷為空nil的實(shí)現(xiàn)代碼

    golang interface判斷為空nil的實(shí)現(xiàn)代碼

    這篇文章主要介紹了golang interface判斷為空nil的實(shí)現(xiàn)代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評論