如何在Golang中使用JSON?相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)建站是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)建站推出碧江免費(fèi)做網(wǎng)站回饋大家。
golang是一種編譯語(yǔ)言,可以將代碼編譯為機(jī)器代碼,編譯后的二進(jìn)制文件可以直接部署到目標(biāo)機(jī)器而無(wú)需額外的依賴,所以golang的性能優(yōu)于其他的解釋性語(yǔ)言,且可以在golang中使用goroutine來(lái)實(shí)現(xiàn)并發(fā)性,它提供了一個(gè)非常優(yōu)雅的goroutine調(diào)度程序系統(tǒng),可以很容易地生成數(shù)百萬(wàn)個(gè)goroutine。
痛點(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)確定的。
看完上述內(nèi)容,你們掌握如何在Golang中使用JSON的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!