如何在Go 中處理JSON

2023/09/19閱讀時間約 11 分鐘


raw-image

👨‍💻 簡介

今天的encoding/json package是我日常在開發web時很常用到的package之一,主要是用來將Go struct和 JSON 之間進行轉換。主要功能為資料序列化(marshalling)和反序列化(unmarshalling)。

主要功能

encoding/json package 主要用來將 Go struct轉換為 JSON 格式(marshalling)以及將 JSON 資料轉換為 Go struct(unmarshalling)。以下是一些主要功能:

將 Go struct轉換為 JSON

使用 json.Marshal 函數可以將 Go struct轉換為 JSON 格式的資料。

package main

import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
person := Person{Name: "Alan", Age: 25}
jsonData, err := json.Marshal(person)
if err != nil {
fmt.Println("JSON 編碼失敗:", err)
return
}

fmt.Println(string(jsonData))
// 輸出: {"name":"Alan","age":25}
}

在上面的範例中,我們先定義了一個 Person struct,然後使用 json.Marshal 函數將 Person 轉換為 JSON 資料。

將 JSON 資料轉換為 Go struct

使用 json.Unmarshal 函數可以將 JSON 資料轉換為 Go struct。

package main

import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
jsonData := []byte(`{"name":"Bob","age":30}`)
var person Person

err := json.Unmarshal(jsonData, &person)
if err != nil {
fmt.Println("JSON 解碼失敗:", err)
return
}

fmt.Println("姓名:", person.Name)
fmt.Println("年齡:", person.Age)
// 輸出:
// 姓名: Bob
// 年齡: 30
}

反轉則是使用 json.Unmarshal 函數將 JSON 資料轉換為 Person 的struct。

自定義 JSON 鍵名

當需要API顯示自定義 JSON 欄位鍵名時,可以在 Go struct的欄位上使用 json 標籤來自定義 JSON 鍵名,方便與外部 API 或其他系統的格式相同。

package main

import (
"encoding/json"
"fmt"
)
type Person struct {
FullName string `json:"full_name"`
Age int `json:"age"`
}
func main() {
person := Person{FullName: "Charlie Brown", Age: 10}
jsonData, err := json.Marshal(person)
if err != nil {
fmt.Println("JSON 編碼失敗:", err)
return
}

fmt.Println(string(jsonData))
// 輸出: {"full_name":"Charlie Brown","age":10}
}

在這個範例中,我們使用 json 標籤來指定 FullName 欄位在 JSON 中的名稱為 “full_name”。

常見用法

解析複雜的 JSON 資料

encoding/json package 可以處理複雜的 JSON 資料,包括嵌套struct和陣列。

package main

import (
"encoding/json"
"fmt"
)
type Address struct {
City string `json:"city"`
Country string `json:"country"`
}
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Address Address `json:"address"`
}
func main() {
jsonData := []byte(`{ "name": "Alan", "age": 25, "address": { "city": "Taichung", "country": "Taiwan" } }`)

var person Person

err := json.Unmarshal(jsonData, &person)
if err != nil {
fmt.Println("JSON 解碼失敗:", err)
return
}

fmt.Println("姓名:", person.Name)
fmt.Println("年齡:", person.Age)
fmt.Println("地址:", person.Address.Country,person.Address.City )
// 輸出:
// 姓名: Alan
// 年齡: 25
// 地址: Taiwan Taichung
}

在這個範例中,我們定義了 AddressPerson 兩個struct,其中 Person 包含一個嵌套的 Address struct。我們使用 json.Unmarshal 函數解析嵌套struct的 JSON 資料。

處理 JSON 陣列

encoding/json package 也能夠處理 JSON 陣列。

package main

import (
"encoding/json"
"fmt"
)
type Item struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
jsonData := []byte(`[ {"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}, {"id": 3, "name": "Item 3"} ]`)
var items []Item

err := json.Unmarshal(jsonData, &items)
if err != nil {
fmt.Println("JSON 解碼失敗:", err)
return
}
for _, item := range items {
fmt.Printf("ID: %d, 名稱: %s\n", item.ID, item.Name)
}
// 輸出:
// ID: 1, 名稱: Item 1
// ID: 2, 名稱: Item 2
// ID: 3, 名稱: Item 3
}

可以看到,我們定義了 Item struct,然後使用 json.Unmarshal 函數解析包含 JSON 陣列的 JSON 資料。

📚 參考資料

16會員
75內容數
golang
留言0
查看全部
發表第一個留言支持創作者!