使用Go進行JSON處理

封送和解封JSON的基礎知識

JSON代表JavaScript對象表示法,這是交換結構化數據的一種非常方便的方法。而且它非常流行,尤其是在與API交互時。

Go在其標準庫中提供了對JSON的頂級支持,encoding/json包裹

與鬆散類型的語言相比,解碼JSON更為複雜。在JavaScript中,您所需要做的就是JSON.parse()。 Python有json.loads(),而PHP具有json_decode()。它們只是轉儲值而沒有問題,但是要進行強類型化,您需要做更多的工作來匹配類型。

JSON具有3種基本類型:布爾值數字弦樂,結合使用數組對象建立復雜的結構。

Go的術語調用元帥從數據結構生成JSON字符串的過程,以及解組將JSON解析為數據結構的行為。

JSON字符串

input := `{"firstname": "Bill", "surname": "Gates"}`

解組JSON

這是一個取自JSON的示例Mozilla的MDN

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

我們如何將其解析為Go數據結構?當然,我們需要一個匹配的數據結構。我們有5種基本類型和一系列對象。讓我們從基本類型開始:

type squad struct {
    SquadName string
    HomeTown string
    Formed int
    SecretBase string
    Active bool
}

我們需要將JSON定義為[]byte, 像這樣:

input := []byte(`
    {
        "squadName": "Super hero squad",
        [...]
    }
`)

我們可以將JSON解組到一個小隊實例:

s := squad{}
err := json.Unmarshal(input, &s)
if err != nil {
    panic(err)
}
fmt.Printf("%v", s)

這將打印

{Super hero squad Metro City 2016 Super tower true}

請注意,對於JSON值與結構之間缺少匹配的抱怨,我們沒有任何錯誤,它們將被忽略。

讓我們確保json.Unmarshal()將獲得我們所有的字段,其中包括:

type squad struct {
	SquadName  string
	HomeTown   string
	Formed     int
	SecretBase string
	Active     bool
	Members    []Member
}

type Member struct { Name string Age int SecretIdentity string Powers []string }

請記住在您的結構中具有公共(大寫)屬性。

重命名JSON字段名稱

在這種情況下,一切都很好,因為JSON具有兼容的文件名。如果要將JSON映射到結構中的其他字段怎麼辦?

例如,如果將會員名稱傳遞為member_name,但您希望將其存儲在Name反而?

使用以下語法:

type Member struct {
	Name string `json:"member_name"`
}

忽略JSON字段

使用以下語法:

type Member struct {
	Name string `json:"-"`
}

封送/取消封送時,“名稱”字段將被忽略。

轉換JSON字段類型

您可以使用標記來註釋將JSON轉換為的類型:

type Member struct {
    Age       int `json:"age,string"`
}

成員結構具有一個Age表示為int。如果您希望它成為一個string相反,但JSON傳遞了int

使用類型註釋:

type Member struct {
    Age       json.Number `json:"age,Number"`
}

Number類型是以下項的別名string

了解有關中的標籤的更多信息轉到標籤說明

元帥JSON

現在,我們可能想從我們的數據結構中構建一個JSON字符串。例如,這可能是一個使用國家/地區代碼並以JSON格式返回相應國家/地區詳細信息的程序。

package main

import ( “encoding/json” “fmt” )

type country struct { Name string }

func main() { country_code := “US”

<span style="color:#a6e22e">the_country</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">country</span>{}

<span style="color:#66d9ef">switch</span> <span style="color:#a6e22e">country_code</span> {
<span style="color:#66d9ef">case</span> <span style="color:#e6db74">"US"</span>:
	<span style="color:#a6e22e">the_country</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">"United States"</span>
}

<span style="color:#a6e22e">c</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Marshal</span>(<span style="color:#a6e22e">the_country</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
	panic(<span style="color:#a6e22e">err</span>)
}

<span style="color:#75715e">// c is now a []byte containing the encoded JSON

fmt.Print(string(c)) }

執行後,該程序將打印{"Name":"United States"}

json.Marshal()返回一個[]byte,因此在傳遞給時必須將其轉換為字符串fmt.Print(),否則您會看到一個看起來毫無意義的數字列表(但它們是有意義的,因為它們是組成字符串的實際字節)。

json.Marshal()將正確處理基本類型和合成類型,例如切片和地圖。

閱讀更多

閱讀更多在圍棋博客上和在encoding/json打包文件


更多教程: