精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go標準庫:Json解析陷阱與版本變動時的偷懶技巧

開發 后端
日常工作中,最常用的數據傳輸格式就是json,而encoding/json庫是內置做解析的庫。這一節來看看它的用法,還有幾個日常使用中隱晦的陷阱和處理技巧。

 [[414537]]

本文轉載自微信公眾號「機智的程序員小熊」,作者小熊。轉載本文請聯系機智的程序員小熊公眾號。

日常工作中,最常用的數據傳輸格式就是json,而encoding/json庫是內置做解析的庫。這一節來看看它的用法,還有幾個日常使用中隱晦的陷阱和處理技巧。

  • json 與 struct
  • 解析
  • 反解析
  • 陷阱 1、忘記取地址
  • 陷阱 2、大小寫
  • 陷阱 3、十六進制或其他非 UTF8 字符串
  • 陷阱 4、數字轉 interface{}
  • 神技、版本變更兼容
  • 小結

json 與 struct

一個常見的接口返回內容如下:

  1.   "data": { 
  2.     "items": [ 
  3.       { 
  4.         "_id": 2 
  5.       } 
  6.     ], 
  7.     "total_count": 1 
  8.   }, 
  9.   "message"""
  10.   "result_code": 200 

在golang中往往是要把json格式轉換成結構體對象使用的。

在新版Goland粘貼json會自動生成結構體,也可以在網上搜到現成的工具完成自動轉換。

  1. type ResponseData struct { 
  2.  Data struct { 
  3.   Items []struct { 
  4.    Id int `json:"_id"
  5.   } `json:"items"
  6.   TotalCount int `json:"total_count"
  7.  } `json:"data"
  8.  Message    string `json:"message"
  9.  ResultCode int    `json:"result_code"

用反斜杠加注解的方式表明屬于json中哪個字段,要注意不應該嵌套層數過多,否則難以閱讀容易出錯。

一般把內部結構體提出來,方便其他業務另做他用。

  1. type ResponseData struct { 
  2.  Data struct { 
  3.   Items []Body `json:"items"
  4.   TotalCount int64 `json:"total_count"
  5.  } `json:"data"
  6.  Message    string `json:"message"
  7.  ResultCode int64  `json:"result_code"
  8.  
  9. type Body struct { 
  10.  ID int `json:"_id"

解析

解析就是把json字符串轉成struct類型。如下,第一個參數為字節數組,第二個為接收的結構體實體地址。如有報錯返回錯誤信息,如沒有返回nil。

  1. //函數簽名 
  2. func Unmarshal(data []byte, v interface{}) error 
  3. // 用法 
  4. err := json.Unmarshal([]byte(jsonStr), &responseData) 

完整代碼如下

  1. func foo() { 
  2.  jsonStr := `{"data":{"items":[{"_id":2}],"total_count":1},"message":"","result_code":200}` 
  3.  //把string解析成struct 
  4.  var responseData ResponseData 
  5.  err := json.Unmarshal([]byte(jsonStr), &responseData) 
  6.  if err != nil { 
  7.   fmt.Println("parseJson error:" + err.Error()) 
  8.   return 
  9.  } 
  10.  fmt.Println(responseData) 

輸出如下,和java的toString不同,go會直接輸出了值,如有需要要自行實現并綁定ToString方法。

  1. {{[{2}] 1}  200} 

反解析

第一步,復習初始化結構體的方法。

  1. r := ResponseData{ 
  2.     Data: struct { 
  3.         Items      []Body `json:"items"
  4.         TotalCount int64  `json:"total_count"
  5.     }{ 
  6.         Items: []Body{ 
  7.             {ID: 1}, 
  8.             {ID: 2}, 
  9.         }, 
  10.         TotalCount: 1, 
  11.     }, 
  12.     Message:    ""
  13.     ResultCode: 200, 

如上,無類型的結構體Data需要明確把類型再寫一遍,再為其賦值。[]Body因為是列表類型,內部如上賦值即可。

反解析函數簽名如下,傳入結構體,返回編碼好的[]byte,和可能的報錯信息。

  1. func Marshal(v interface{}) ([]byte, error) 

完整代碼如下

  1. func bar() { 
  2.  r := ResponseData{ 
  3.   .... 
  4.  } 
  5.  //把struct編譯成string 
  6.  resBytes, err := json.Marshal(r) 
  7.  if err != nil { 
  8.   fmt.Println("convertJson error: " + err.Error()) 
  9.  } 
  10.  fmt.Println(string(resBytes)) 

輸出

  1. {"data":{"items":[{"_id":1},{"_id":2}],"total_count":1},"message":"","result_code":200} 

陷阱 1、忘記取地址

解析的代碼在結尾處應該是&responseData) 忘記取地址會導致無法賦值成功,返回報錯。

  1. err := json.Unmarshal([]byte(jsonStr), responseData) 

輸出報錯

  1. json: Unmarshal(non-pointer main.ResponseData) 

陷阱 2、大小寫

定義一個簡單的結構體來演示這個陷阱。

  1. type People struct { 
  2.  Name string `json:"name"
  3.  age  int    `json:"age"

變量如果需要被外部使用,也就是java中的public權限,定義時首字母必須用大寫,這也是Go約定的權限控制。

  1. type People struct 

要用來解析json的struct內部,假如使用了小寫作為變量名,會導致無法解析成功,而且不會報錯!

  1. func err1() { 
  2.  reqJson := `{"name":"minibear2333","age":26}` 
  3.  var person People 
  4.  err := json.Unmarshal([]byte(reqJson), &person) 
  5.  if err != nil {...} 
  6.  fmt.Println(person) 

輸出 0,沒有成功取到age字段。

  1. {minibear2333 0} 

這是因為標準庫中是使用反射來獲取的,私有字段是無法獲取到的,源碼內部不知道有這個字段,自然無法顯示報錯信息。

我以前沒有用自動解析,手敲上去結構體,很容易出現這樣的問題,把某個字段首字母弄成小寫。好在編譯器會有提示。

陷阱 3、十六進制或其他非 UTF8 字符串

Go 默認使用的字符串編碼是 UTF8 編碼的。直接解析會出錯

  1. func err2() { 
  2.  raw := []byte(`{"name":"\xc2"}`) 
  3.  var person People 
  4.  if err := json.Unmarshal(raw, &person); err != nil { 
  5.   fmt.Println(err) 
  6.  } 

輸出

  1. invalid character 'x' in string escape code 

要特別注意,加上反斜杠轉義可以成功,或者使用base64編碼成字符串,這下子單元測試的重要性就體現出來了。如下:

  1. raw := []byte(`{"name":"\\xc2"}`) 
  2. raw := []byte(`{"name":"wg=="}`) 

其他需要注意的是編碼如果不是UTF-8格式,那么Go會用 ? (U+FFFD) 來代替無效的 UTF8,這不會報錯,但是獲得的字符串可能不是你需要的結果。

陷阱 4、數字轉 interface{}

因為默認編碼無類型數字視為 float64 。如果想用類型判斷語句為int會直接panic。

  1. func err4() { 
  2.  var data = []byte(`{"age": 26}`) 
  3.  var result map[string]interface{} 
  4.  ... 
  5.  var status = result["age"].(int) //error 
  • 上面的代碼隱含一個知識點,json中value是簡單類型時,可以直接解析成字典。
  • 如果有嵌套,那么內部類型也會解析成字典。
  • 解析成字典,輸出的時候有類似ToString的效果。

運行時 Panic:

  1. panic: interface conversion: interface {} is float64, not int 
  2.  
  3. goroutine 1 [running]: 
  4. main.err4() 

可以先轉換成float64再轉換成int

其實還有幾種方法,太麻煩了也沒有必要,就不做特別介紹了。

神技、版本變更兼容

你有沒有遇到過一種場景,一個接口更新了版本,把json的某個字段變更了,在請求的時候每次都定義兩套struct。

比如Age在版本 1 中是int在版本 2 中是string,解析的過程中就會出錯。

  1. json: cannot unmarshal number into Go struct field People.age of type string 

我在下面介紹一個技巧,可以省去每次解析都要轉換的工作。

我在源碼里面看到,無論反射獲得的是哪種類型都會去調用相應的解析接口UnmarshalJSON。

結合前面的知識,在Go里面看起來像鴨子就是鴨子,我們只要實現這個方法,并綁定到結構體對象上,就可以讓源碼來調用我們的方法。

  1. type People struct { 
  2.     Name string `json:"name"
  3.     Age  int    `json:"_"
  4. func (p *People) UnmarshalJSON(b []byte) error { 
  5.  ... 
  • 使用下劃線表示此類型不解析。
  • 必須用指針的方式綁定方法。
  • 必須與 interface{}中定義的方法簽名完全一致。

一共有四個步驟

1、定義臨時類型。用來接受非json:"_"的字段,注意用的是type關鍵字。

  1. type tmp People 

2、用中間變量接收 json 串,tmp 以外的字段用來接受json:"_"屬性字段

  1. var s = &struct { 
  2.     tmp 
  3.     // interface{}類型,這樣才可以接收任意字段 
  4.     Age interface{} `json:"age"
  5. }{} 
  6. // 解析 
  7. err := json.Unmarshal(b, &s) 

3、判斷真實類型,并類型轉換

  1. switch t := s.Age.(type) { 
  2. case string: 
  3.     var age int 
  4.     age, err = strconv.Atoi(t) 
  5.     if err != nil {...} 
  6.     s.tmp.Age = age 
  7. case float64: 
  8.     s.tmp.Age = int(t) 

4、tmp 類型轉換回 People,并賦值

  1. *p = People(s.tmp) 

小結

通過本節,我們掌握了標準庫中json解析和反解析的方法,以及很有可能日常工作中踩到的幾個坑。它們是:

  • 陷阱 1、忘記取地址
  • 陷阱 2、大小寫
  • 陷阱 3、十六進制或其他非 UTF8 字符串
  • 陷阱 4、數字轉 interface{}

版本變量時兼容技巧

最后分享的技巧在實際使用中,更加靈活。

留一個作業:假如有v1和v2不同的兩個版本json幾乎完成不同,業務邏輯已經使用v1版本,是否可以把v2版本轉換成v1版本,幾乎不用改動業務邏輯?

提示:可以通過深拷貝把v2版本解析出來的結構體完全轉換成v1版本的結構體。

要求:必須使用實現 UnmarshalJSON的技巧。

本文轉載自微信公眾號「機智的程序員小熊」,可以通過以下二維碼關注。轉載本文請聯系機智的程序員小熊公眾號。

 

責任編輯:武曉燕 來源: 機智的程序員小熊
相關推薦

2023-08-28 08:40:23

Sonic開發JSON

2018-08-02 15:09:20

PyTorch深度學習神經網絡

2024-09-29 16:04:14

2024-06-12 08:54:49

Go切片參數

2024-07-11 08:50:05

Go語言errors

2023-06-26 00:03:55

Go語言類型

2023-04-02 23:13:07

Go語言bufio

2021-07-08 23:53:44

Go語言拷貝

2021-08-13 12:05:15

Goneturl

2022-12-07 08:47:48

2010-01-06 16:41:40

解析JSON

2025-05-12 01:33:00

異步函數Promise

2009-07-16 09:12:16

程序員偷懶技巧

2024-06-20 13:38:03

2010-02-06 14:28:38

C++標準輸入輸出

2023-07-03 00:44:26

Go語言MySQL

2022-12-02 10:11:50

2010-01-05 16:41:48

JSON 標準

2025-10-09 04:22:00

2014-01-14 09:10:53

GoHTTP內存泄漏
點贊
收藏

51CTO技術棧公眾號

欧美久久久久久| 中文亚洲视频在线| 18岁网站在线观看| 成年人视频免费在线观看| 美女一区二区三区| 欧美人在线观看| 亚洲av无码成人精品国产| 国产成人午夜性a一级毛片| 亚洲精品乱码久久久久久| 国产区二精品视| 五月婷婷丁香在线| 国产综合久久| 尤物tv国产一区| 中文字幕无码毛片免费看| 日韩精品专区| 亚洲一区二区精品久久av| 日韩精品在在线一区二区中文| 国产ts人妖调教重口男| 三级欧美在线一区| 久久久欧美一区二区| 精品一区二区三孕妇视频| 超碰成人免费| 欧美一区二区三区在线电影| 国产女女做受ⅹxx高潮| 最新国产在线拍揄自揄视频| 国产欧美日韩麻豆91| 国产高清精品一区| 国产精品区在线观看| 亚洲一本视频| 日韩性生活视频| 蜜桃精品一区二区| 国产精品15p| 日韩三级在线观看| 91国模大尺度私拍在线视频| 成人福利网站在线观看| 亚洲视频 欧美视频| 影音国产精品| 九九热这里只有精品免费看| 国产无遮挡在线观看| 久久不见久久见中文字幕免费| 欧美精品一区二区在线观看| 肉色超薄丝袜脚交| 亚州精品国产| 欧美日韩国产综合一区二区| av免费网站观看| 小视频免费在线观看| 午夜欧美在线一二页| 妞干网在线播放| 色呦呦在线播放| 亚洲欧美日韩人成在线播放| 男女啪啪的视频| 尤物网在线观看| 欧美韩国一区二区| 欧美在线视频二区| 国产日本在线观看| 国产日韩欧美亚洲| 日韩电影免费观看高清完整| 好男人免费精品视频| 国产午夜亚洲精品午夜鲁丝片| 欧美18视频| 国产在线观看黄| av在线一区不卡| 91麻豆6部合集magnet| 久99久在线| 免费在线看v| 日本一区二区三区在线观看| 亚洲精品白虎| 好吊日视频在线观看| 亚洲九九爱视频| 人人妻人人澡人人爽欧美一区双 | 喜爱夜蒲2在线| a黄色片在线观看| 亚洲国产精品影院| 又粗又黑又大的吊av| 欧美xxx网站| 欧美性感一类影片在线播放| 最近中文字幕一区二区| 图片一区二区| 亚洲精品一区二区在线观看| 人妻丰满熟妇av无码久久洗澡| 亚洲人成精品久久久| 日韩在线资源网| 日本天堂中文字幕| 在线亚洲欧美| 国产精品中文字幕在线观看| 国产suv一区二区| www久久精品| 一区二区在线观看网站| 黄网站在线观| 欧美在线高清视频| 色欲欲www成人网站| 亚瑟一区二区三区四区| 精品国偷自产在线| 日本熟妇乱子伦xxxx| 蜜桃视频一区二区三区在线观看| 超碰97国产在线| 成人影视在线播放| 亚洲成人av一区| 亚洲美女爱爱视频| 精品亚洲自拍| 久久天天躁狠狠躁老女人| 国产精品一区二区6| 精品写真视频在线观看| 久久久久se| 色女人在线视频| 欧美特级限制片免费在线观看| 国产精品一区二区在线免费观看| jlzzjlzz亚洲女人| 97在线精品视频| 国产91视频在线| 国产欧美日韩麻豆91| 免费看又黄又无码的网站| 日韩成人综合网站| 精品在线欧美视频| 久久久久久久九九九九| 蜜桃久久久久久| 久久日韩精品| 丁香花在线电影小说观看| 欧美老肥妇做.爰bbww| 中出视频在线观看| 精品69视频一区二区三区Q| 国产乱人伦真实精品视频| 日本私人网站在线观看| 夜色激情一区二区| www.色就是色.com| 成人av二区| 欧洲午夜精品久久久| 欧美熟妇另类久久久久久不卡| 国产精品初高中害羞小美女文| 99蜜桃臀久久久欧美精品网站| 亚洲综合网狠久久| 欧美精品亚州精品| 国产精品热久久| 国产精品国产三级国产普通话三级| 一本色道无码道dvd在线观看| 国产精品x8x8一区二区| 欧美黑人狂野猛交老妇| av一级黄色片| 一区二区三区免费看视频| 久久婷婷中文字幕| 欧美电影一区| 国产噜噜噜噜久久久久久久久| av基地在线| 欧美日韩一级黄| 欧美老女人性生活视频| 日本在线不卡视频| 午夜精品区一区二区三| 91久久久久久白丝白浆欲热蜜臀| 亚洲欧美一区二区激情| 蜜臀精品一区二区三区| 久久精品亚洲麻豆av一区二区| 成人免费观看毛片| 国产99亚洲| 国产激情999| 成人精品一区二区三区免费| 欧美亚洲国产一区在线观看网站 | 奇米4444一区二区三区| 青青久草在线| 日本道色综合久久| 日韩丰满少妇无码内射| 日韩电影在线看| 亚洲午夜精品久久久中文影院av | 欧美精品一卡二卡| 放荡的美妇在线播放| 国产成人精品一区二区三区四区 | 久久一区二区三区超碰国产精品| 蜜桃91精品入口| 国产精品成人国产| 麻豆乱码国产一区二区三区| www.色婷婷.com| 无码av中文一区二区三区桃花岛| 性欧美成人播放77777| 日韩精品一二三区| 咪咪色在线视频| 国产伦精品一区二区三区免费优势| 性视频1819p久久| 黄色毛片在线看| 3atv在线一区二区三区| 日韩av免费网址| 日本一区二区三区高清不卡| 欧美激情第四页| 亚洲深夜激情| 一区二区三区四区五区视频| 综合成人在线| 国产精品人成电影| 最新av在线播放| 精品亚洲一区二区| 国产巨乳在线观看| 精品久久久中文| 91精品少妇一区二区三区蜜桃臀| 成人黄色av网站在线| 天天碰免费视频| 国产精品magnet| 日韩三级电影网站| 综合伊人久久| 国产精品一区二区三区毛片淫片 | 综合一区在线| 欧美日韩一区综合| 日韩欧美久久| 国产精品久久久久久久久久久新郎| 91蜜桃在线视频| 亚洲男人天堂古典| 精品人妻一区二区三区蜜桃| 色诱亚洲精品久久久久久| 欧美人禽zoz0强交| 国产午夜精品久久| 人妻激情偷乱频一区二区三区| 奇米精品一区二区三区四区| 欧美视频在线观看网站 | 欧美精品久久久久久久久久久| 精品九九在线| 国产专区一区二区三区| 成人动漫视频在线观看| 国产成人精品久久| 僵尸再翻生在线观看| 超碰97人人做人人爱少妇| 岛国最新视频免费在线观看| 亚洲激情视频网站| www.综合色| 欧美高清精品3d| 中文字幕在线播放日韩| 色婷婷国产精品久久包臀| 国产无遮挡又黄又爽又色| 亚洲狼人国产精品| 91免费公开视频| 国产精品国产三级国产普通话99 | 91欧美一区二区三区| 肉肉av福利一精品导航| 男人操女人免费软件| 黄色亚洲大片免费在线观看| 在线观看日韩羞羞视频| 不卡日本视频| 日韩国产欧美一区| 欧美激情在线精品一区二区三区| 精品欧美日韩| 美国成人xxx| 精品麻豆av| 麻豆一区二区麻豆免费观看| 国模精品一区二区三区| 欧美黑白配在线| 久久96国产精品久久99软件| 国产精品qvod| 久久人人九九| 久久最新网址| 五码日韩精品一区二区三区视频| 视频国产一区| 色姑娘综合网| 98精品久久久久久久| 91手机视频在线| 欧美日本中文| 国产va亚洲va在线va| 日韩午夜精品| 红桃av在线播放| 美女久久一区| 一区二区三区 欧美| 美女视频黄a大片欧美| 天天操天天干天天做| 国产一区二区三区在线观看免费视频| 亚洲一区二区图片| 懂色av一区二区三区免费看| 国产激情视频网站| 久久嫩草精品久久久精品| 丰满的亚洲女人毛茸茸| 亚洲同性同志一二三专区| 妺妺窝人体色www聚色窝仙踪| 亚洲成人免费视频| 好吊妞视频一区二区三区| 91成人免费在线视频| 亚洲一区二区色| 日韩视频123| 日本国产在线| 日韩一级黄色av| 成人女同在线观看| 国产成人高潮免费观看精品| 欧美一区二区三区婷婷| 超碰在线97av| 菠萝蜜一区二区| 轻点好疼好大好爽视频| 久久一二三区| 中国男女全黄大片| 久久综合狠狠综合久久综合88| 91成人精品一区二区| 亚洲精品欧美在线| 国产黄色免费观看| 777亚洲妇女| 三级在线电影| 久久亚洲精品成人| 日本蜜桃在线观看视频| 国产综合久久久久久| 国产乱人伦丫前精品视频| 性欧美.com| 在线午夜精品| 特级黄色片视频| 26uuu色噜噜精品一区二区| 色哟哟一一国产精品| 狠狠色香婷婷久久亚洲精品| 国产免费久久久| 亚洲欧洲日产国码av系列天堂| 精品麻豆一区二区三区| 秋霞av国产精品一区| 久久伊人精品| 午夜一区二区三视频在线观看| 欧美午夜不卡影院在线观看完整版免费| 无码内射中文字幕岛国片| 国产suv精品一区二区三区| 美女100%露胸无遮挡| 亚洲18色成人| 国产成年妇视频| 这里精品视频免费| 无遮挡爽大片在线观看视频| 亚洲free嫩bbb| 成人羞羞网站入口| 777777av| 成人永久看片免费视频天堂| 四虎地址8848| 欧美日韩一区二区三区四区五区| 香蕉视频成人在线| 欧美黑人又粗大| 国产精品久久久久久久久久辛辛| 日本精品视频一区| 一区二区日本视频| 99久久久无码国产精品性波多| 综合久久久久综合| 中文字幕欧美色图| 亚洲片av在线| 91精品论坛| 精品一卡二卡三卡四卡日本乱码 | 一区二区日韩av| 国产又粗又猛又爽又黄视频| 在线播放亚洲激情| 偷拍精品精品一区二区三区| 精品视频第一区| 亚洲人成久久| 中文在线永久免费观看| 亚洲午夜视频在线观看| 精品人妻av一区二区三区| 北条麻妃一区二区三区中文字幕| 国产精品麻豆成人av电影艾秋| 午夜老司机精品| 免费观看成人av| 大胸美女被爆操| 欧美日韩国产一级| 欧美日韩xx| 91久久精品美女高潮| 久久久久久久久久久9不雅视频| 中文字幕第88页| 一区在线中文字幕| 国产乱码久久久| 九九热这里只有在线精品视| 91精品入口| 免费看国产曰批40分钟| 99精品国产热久久91蜜凸| 天天综合天天干| 亚洲一级免费视频| jizz久久久久久| 一区二区三区四区| 国产成人av影院| 日韩精品视频播放| 亚洲欧美综合区自拍另类| 巨大黑人极品videos精品| 中文字幕中文字幕99 | 91免费人成网站在线观看18| 91精品一区二区三区综合在线爱| 成人三级做爰av| 五月综合激情日本mⅴ| 激情综合闲人网| 成人国产精品一区二区| 欧美一区91| 白丝女仆被免费网站| 欧美日韩国产综合一区二区| 污网站在线免费看| 麻豆av福利av久久av| 蜜臀av一区二区在线免费观看| 久久久久久视频| 亚洲成人亚洲激情| 国产成人精品一区二三区在线观看 | 久久久久久香蕉| 亚洲欧洲日本在线| 欧美一级在线免费观看| 热久久这里只有| 久久精品影视| 久久无码人妻精品一区二区三区| 欧美视频一区二区在线观看| 日本动漫理论片在线观看网站| 精品无人区一区二区三区| 日韩国产精品大片| 欧美成人三级视频| 亚洲性日韩精品一区二区| 久久69av| 国产成人手机视频| 亚洲午夜精品在线| 中文字幕日本在线观看| 高清视频在线观看一区| 奇米一区二区三区| 日韩大片免费在线观看| 最近2019年中文视频免费在线观看| 成人看片爽爽爽| 亚洲精品视频三区| 欧美色道久久88综合亚洲精品| 里番在线观看网站|