一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - 使用Go語言解析動態JSON格式的方法

使用Go語言解析動態JSON格式的方法

2020-05-12 11:18HP''''S Memory Golang

本篇文章主要介紹了使用Go語言解析動態JSON格式的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

通常使用Golang encoding/json 標準庫可以方便的編碼/解析JSON數據,但是前提需要定義struct數據結構。特別是解析未知結構的JSON數據時,原有方法很難滿足需求了,本文主要介紹動態解析JSON格式。

Go語言的JSON 庫

Go語言自帶的JSON轉換庫為 encoding/json

1.1)其中把對象轉換為JSON的方法(函數)為 json.Marshal(),其函數原型如下

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

也就是說,這個函數接收任意類型的數據 v,并轉換為字節數組類型,返回值就是我們想要的JSON數據和一個錯誤代碼。當轉換成功的時候,這個錯誤代碼為nil

在進行對象轉換為 JSON 的過程中,會遵循如下幾條規則:

  1. 布爾型轉換為 JSON 后仍是布爾型 , 如true -> true
  2. 浮點型和整數型轉換后為JSON里面的常規數字,如 1.23 -> 1.23
  3. 字符串將以UTF-8編碼轉化輸出為Unicode字符集的字符串,特殊字符比如<將會被轉義為\u003c
  4. 數組和切片被轉換為JSON 里面的數組,[]byte類會被轉換為base64編碼后的字符串,slice的零值被轉換為null
  5. 結構體會轉化為JSON對象,并且只有結構體里邊以大寫字母開頭的可被導出的字段才會被轉化輸出,而這些可導出的字段會作為JSON對象的字符串索引
  6. 轉化一個map 類型的數據結構時,該數據的類型必須是 map[string]T(T 可以是encoding/json 包支持的任意數據類型)

1.2)把 JSON 轉換回對象的方法(函數)為 json.Unmarshal(),其函數原型如下

func Unmarshal(data [] byte, v interface{}) error

這個函數會把傳入的 data 作為一個JSON來進行解析,解析后的數據存儲在參數 v 中。這個參數 v 也是任意類型的參數(但一定是一個類型的指針),原因是我們在是以此函數進行JSON 解析的時候,這個函數不知道這個傳入參數的具體類型,所以它需要接收所有的類型。

那么,在進行解析的時候,如果JSON 和 對象的結構不對口會發生什么呢,這就需要解析函數json.Unmarshal()遵循以下規則

json.Unmarshal() 函數會根據一個約定的順序查找目標結構中的字段,如果找到一個即發生匹配。那什么是找到了呢?關于“找到了”又有如下的規則:假設一個JSON對象有個名為"Foo"的索引,要將"Foo"所對應的值填充到目標結構體的目標字段上,json.Unmarshal() 將會遵循如下順序進行查找匹配

  1. § 一個包含Foo 標簽的字段
  2. §  一個名為Foo 的字段
  3. § 一個名為Foo 或者Foo 或者除了首字母其他字母不區分大小寫的名為Foo 的字段。 這些字段在類型聲明中必須都是以大寫字母開頭、可被導出的字段。

注意:如果JSON中的字段在Go目標類型中不存在,json.Unmarshal() 函數在解碼過程中會丟棄該字段。

當JSON 的結構是未知的時候,會遵循如下規則:

  1. § JSON中的布爾值將會轉換為Go中的bool類型
  2. § 數值會被轉換為Go中的float64類型
  3. § 字符串轉換后還是string類型
  4. § JSON數組會轉換為[]interface{} 類型
  5. § JSON對象會轉換為map[string]interface{}類型
  6. § null值會轉換為nil

注意:在Go的標準庫encoding/json包中,允許使用map[string]interface{}和[]interface{} 類型的值來分別存放未知結構的JSON對象或數組

1、傳統方法

比如 User 數據結構如下:

?
1
2
3
4
type User struct {
 Name string `json:"name"`
 Age int  `json:"age"`
}

在定義struct字段的時候,可以在字段后面添加tag,來控制encode/decode的過程:是否要 decode/encode 某個字段,JSON 中的字段名稱是什么。字段名首字母控制字段的可見性,若要輸出到JSON,首字母需要大寫。

三種tag:

- :不要解析這個字段

omitempty :當字段為空(默認值)時,不要解析這個字段。比如 false、0、nil、長度為 0 的 array,map,slice,string

FieldName :當解析 json 的時候,使用這個名字

舉例來說吧:

?
1
2
3
4
5
6
// 解析的時候忽略該字段。默認情況下會解析這個字段,因為它是大寫字母開頭的
Field int `json:"-"`
// 解析(encode/decode) 的時候,使用 `other_name`,而不是 `Field`
Field int `json:"other_name"`
// 解析的時候使用 `other_name`,如果struct 中這個值為空,就忽略它
Field int `json:"other_name,omitempty"`

(1)encode

?
1
2
3
4
5
user := User{Name: "test", Age:23}
data, err := json.Marshal(user)
if err != nil {
 fmt.Println(string(data))
}

data 就是 []byte 類型的數組,里面包含了解析為 JSON 之后的數據,可以使用string(data)轉型為string。

(2)decode

要把JSON數據轉換成Go類型的值(Decode),可以使用 json.Unmarshal 。

?
1
2
3
4
5
var user User
err = json.Unmarshal(data, &user)
if err != nil {
 fmt.Errorf("Can not decode data: %v\n", err)
}

2、動態解析

動態JSON結構未知,若使用前面方法需要事先定義數據結構,這與PHP/Python JSON處理非常不同。若不考慮性能,使用simplejson。

(1)simplejson

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
js, err := simplejson.NewJson([]byte(`{
 "test": {
  "string_array": ["asdf", "zxcv"],
  "array": [1, "2", 3],
  "arraywithsubs": [{"subkeyone": 1},
  "bignum": 9223372036854775807,
  "string": "simplejson",
  "bool": true
 }
 }`))
 if err != nil {
  panic("json format error")
 }
 //獲取某個字段值
 s, err := js.Get("test").Get("string").String()
 if err != nil {
  panic(err)
 }
 fmt.Println(s)
 //檢查某個字段是否存在
 _, ok := js.Get("test").CheckGet("string2")
 if ok {
  fmt.Println("存在!")
 } else {
  fmt.Println("不存在")
 }

(2)interface

比如JSON有以下兩種類型:

?
1
2
{"Type":"sound","Msg":{"Description":"dynamite","Authority":"the Bruce Dickinson"}}
{"Type":"cowbell","Msg":{"More":true}}

Msg 具體什么類型實現無法判斷, Msg being a map[string]interface{} :

?
1
2
3
4
5
6
7
8
9
10
11
12
type Envelope struct {
 Type string
 Msg interface{}
}
 
var env Envelope
if err := json.Unmarshal([]byte(input), &env); err != nil {
  log.Fatal(err)
 }
// for the love of Gopher DO NOT DO THIS
var desc string = env.Msg.(map[string]interface{})["description"].(string)
fmt.Println(desc)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.tanhp.com/index.php/archives/450/

延伸 · 閱讀

精彩推薦
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
主站蜘蛛池模板: 四虎永久在线精品国产馆v视影院 | 免费又爽又黄禁片视频在线播放 | 天天白天天谢天天啦 | 国产精品午夜性视频网站 | 狠狠插综合网 | 国产欧美va欧美va香蕉在线观看 | 亚洲欧美日韩国产一区图片 | 亚洲va久久久噜噜噜久久狠狠 | 洗濯屋H纯肉动漫在线观看 武侠艳妇屈辱的张开双腿 午夜在线观看免费观看 视频 | 亚洲成人网导航 | 韩国漂亮美女三级在线观看 | 精品视频 久久久 | 亚洲视频99 | 性关系视频免费网站在线观看 | 九九99热| 精品久久99麻豆蜜桃666 | 免费高清www动漫视频播放器 | 色批网站www | 和日本免费不卡在线v | 久久久久免费视频 | 欧美日韩在线一区二区三区 | 日本一在线中文字幕天堂 | 亚洲国产欧美久久香综合 | 肥胖女人一级毛片 | 四虎永久免费地址ww417 | 欧美18~20性hd| 青青成人福利国产在线视频 | 男人jj视频 | 国产精品青青在线观看香蕉 | 四虎免费在线观看视频 | 国产伦精品一区二区三区免费观看 | 2021国产麻豆剧传媒剧情最新 | 无遮18禁在线永久免费观看挡 | 日本人与黑人做爰视频网站 | 狠狠色成人综合网图片区 | 亚洲天堂在线视频观看 | 192.168.191 | 性导航h| 四虎永久免费地址在线网站 | 欧美综合另类 | 日韩精品一区二区三区中文字幕 |