Go語言將結構體資料儲存為JSON格式資料

2020-07-16 10:05:20
JSON 格式是一種物件文字格式,是當前網際網路最常用的資訊交換格式之一。在Go語言中,可以使用 json.Marshal() 函數將結構體格式的資料格式化為 JSON 格式。

想要使用 json.Marshal() 函數需要我們先引入 encoding/json 包,範例程式碼如下:
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    // 宣告技能結構體
    type Skill struct {
        Name  string
        Level int
    }
    // 宣告角色結構體
    type Actor struct {
        Name   string
        Age    int
        Skills []Skill
    }
    // 填充基本角色資料
    a := Actor{
        Name: "cow boy",
        Age:  37,
        Skills: []Skill{
            {Name: "Roll and roll", Level: 1},
            {Name: "Flash your dog eye", Level: 2},
            {Name: "Time to have Lunch", Level: 3},
        },
    }
    result, err := json.Marshal(a)
    if err != nil {
        fmt.Println(err)
    }
    jsonStringData := string(result)
    fmt.Println(jsonStringData)
}
執行結果如下:

{
    "Name":"cow boy",
    "Age":37,
    "Skills":[
        {
            "Name":"Roll and roll",
            "Level":1
        },
        {
            "Name":"Flash your dog eye",
            "Level":2
        },
        {
            "Name":"Time to have Lunch",
            "Level":3
        }
    ]
}

通過執行結果可以看出我們成功的將結構體資料轉換成了 JSON 格式。

提示:為了便於檢視這裡將輸出結果做了格式化處理。

在轉換 JSON 格式時,JSON 的各個欄位名稱預設使用結構體的名稱,如果想要指定為其它的名稱我們可以在宣告結構體時新增一個`json:" "`標籤,在" "中可以填入我們想要的內容,程式碼如下所示:
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    // 宣告技能結構體
    type Skill struct {
        Name  string `json:"name"`
        Level int    `json:"level"`
    }
    // 宣告角色結構體
    type Actor struct {
        Name   string
        Age    int
        Skills []Skill
    }
    // 填充基本角色資料
    a := Actor{
        Name: "cow boy",
        Age:  37,
        Skills: []Skill{
            {Name: "Roll and roll", Level: 1},
            {Name: "Flash your dog eye", Level: 2},
            {Name: "Time to have Lunch", Level: 3},
        },
    }
    result, err := json.Marshal(a)
    if err != nil {
        fmt.Println(err)
    }
    jsonStringData := string(result)
    fmt.Println(jsonStringData)
}
執行結果如下:

{
    "Name":"cow boy",
    "Age":37,
    "Skills":[
        {
            "name":"Roll and roll",
            "level":1
        },
        {
            "name":"Flash your dog eye",
            "level":2
        },
        {
            "name":"Time to have Lunch",
            "level":3
        }
    ]
}

通過執行結果可以看出,我們成功將 Skill 結構體的 Name 和 Level 欄位轉換成了想要的內容。

我們還可以在上面的標籤的" "中加入 omitempty(使用逗號,與前面的內容分隔),來過濾掉轉換的 JSON 格式中的空值,如下所示:
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    // 宣告技能結構體
    type Skill struct {
        Name  string `json:"name,omitempty"`
        Level int    `json:"level"`
    }
    // 宣告角色結構體
    type Actor struct {
        Name   string
        Age    int
        Skills []Skill
    }
    // 填充基本角色資料
    a := Actor{
        Name: "cow boy",
        Age:  37,
        Skills: []Skill{
            {Name: "", Level: 1},
            {Name: "Flash your dog eye"},
            {Name: "Time to have Lunch", Level: 3},
        },
    }
    result, err := json.Marshal(a)
    if err != nil {
        fmt.Println(err)
    }
    jsonStringData := string(result)
    fmt.Println(jsonStringData)
}
執行結果如下:

{
    "Name":"cow boy",
    "Age":37,
    "Skills":[
        {
            "level":1
        },
        {
            "name":"Flash your dog eye",
            "level":0
        },
        {
            "name":"Time to have Lunch",
            "level":3
        }
    ]
}

通過對比 Skill 結構體的 Name 和 Level 欄位可以看出,Name 欄位的空值被忽略了,而 Level 欄位則沒有。

`json:" "` 標籤的使用總結為以下幾點:
  • FieldName int `json:"-"`:表示該欄位被本包忽略;
  • FieldName int `json:"myName"`:表示該欄位在 JSON 裡使用“myName”作為鍵名;
  • FieldName int `json:"myName,omitempty"`:表示該欄位在 JSON 裡使用“myName”作為鍵名,並且如果該欄位為空時將其省略掉;
  • FieldName int `json:",omitempty"`:該欄位在json裡的鍵名使用預設值,但如果該欄位為空時會被省略掉,注意 omitempty 前面的逗號不能省略