C語言中文網 目錄

Go語言使用匿名結構體解析JSON數據

手機擁有屏幕、電池、指紋識別等信息,將這些信息填充為 JSON 格式的數據。如果需要選擇性地分離 JSON 中的數據則較為麻煩。Go 語言中的匿名結構體可以方便地完成這個操作。

首先給出完整的代碼,然后再講解每個部分。
package main

import (
    "encoding/json"
    "fmt"
)

// 定義手機屏幕
type Screen struct {
    Size       float32 // 屏幕尺寸
    ResX, ResY int     // 屏幕水平和垂直分辨率
}

// 定義電池
type Battery struct {
    Capacity int // 容量
}

// 生成json數據
func genJsonData() []byte {
    // 完整數據結構
    raw := &struct {
        Screen
        Battery
        HasTouchID bool // 序列化時添加的字段:是否有指紋識別
    }{
        // 屏幕參數
        Screen: Screen{
            Size: 5.5,
            ResX: 1920,
            ResY: 1080,
        },

        // 電池參數
        Battery: Battery{
            2910,
        },

        // 是否有指紋識別
        HasTouchID: true,
    }

    // 將數據序列化為json
    jsonData, _ := json.Marshal(raw)

    return jsonData
}

func main() {

    // 生成一段json數據
    jsonData := genJsonData()

    fmt.Println(string(jsonData))

    // 只需要屏幕和指紋識別信息的結構和實例
    screenAndTouch := struct {
        Screen
        HasTouchID bool
    }{}

    // 反序列化到screenAndTouch
    json.Unmarshal(jsonData, &screenAndTouch)

    // 輸出screenAndTouch的詳細結構
    fmt.Printf("%+v\n", screenAndTouch)

    // 只需要電池和指紋識別信息的結構和實例
    batteryAndTouch := struct {
        Battery
        HasTouchID bool
    }{}

    // 反序列化到batteryAndTouch
    json.Unmarshal(jsonData, &batteryAndTouch)

    // 輸出screenAndTouch的詳細結構
    fmt.Printf("%+v\n", batteryAndTouch)
}

定義數據結構

首先,定義手機的各種數據結構體,如屏幕和電池,參考如下代碼:
// 定義手機屏幕
type Screen struct {
    Size       float32  // 屏幕尺寸
    ResX, ResY int      // 屏幕水平和垂直分辨率
}

// 定義電池
type Battery struct {
    Capacity int  // 容量
}
上面代碼定義了屏幕結構體和電池結構體,它們分別描述屏幕和電池的各種細節參數。

準備JSON數據

準備手機數據結構,填充數據,將數據序列化為 JSON 格式的字節數組,代碼如下:
// 生成JSON數據
func genJsonData() []byte {
    // 完整數據結構
    raw := &struct {
        Screen
        Battery
        HasTouchID bool  // 序列化時添加的字段:是否有指紋識別
    }{
            // 屏幕參數
        Screen: Screen{
            Size: 5.5,
            ResX: 1920,
            ResY: 1080,
        },

        // 電池參數
        Battery: Battery{
            2910,
        },

        // 是否有指紋識別
        HasTouchID: true,
    }

    // 將數據序列化為JSON
    jsonData, _ := json.Marshal(raw)

    return jsonData
}
代碼說明如下:
  • 第 4 行定義了一個匿名結構體。這個結構體內嵌了 Screen 和 Battery 結構體,同時臨時加入了 HasTouchID 字段。
  • 第 10 行,為剛聲明的匿名結構體填充屏幕數據。
  • 第 17 行,填充電池數據。
  • 第 22 行,填充指紋識別字段。
  • 第 26 行,使用 json.Marshal 進行 JSON 序列化,將 raw 變量序列化為 []byte 格式的 JSON 數據。

分離JSON數據

調用 genJsonData 獲得 JSON 數據,將需要的字段填充到匿名結構體實例中,通過 json.Unmarshal 反序列化 JSON 數據達成分離 JSON 數據效果。代碼如下:
func main() {

    // 生成一段JSON數據
    jsonData := genJsonData()

    fmt.Println(string(jsonData))

    // 只需要屏幕和指紋識別信息的結構和實例
    screenAndTouch := struct {
            Screen
            HasTouchID bool
    }{}

    // 反序列化到screenAndTouch中
    json.Unmarshal(jsonData, &screenAndTouch)

    // 輸出screenAndTouch的詳細結構
    fmt.Printf("%+v\n", screenAndTouch)

    // 只需要電池和指紋識別信息的結構和實例
    batteryAndTouch := struct {
            Battery
            HasTouchID bool
    }{}

    // 反序列化到batteryAndTouch
    json.Unmarshal(jsonData, &batteryAndTouch)

    // 輸出screenAndTouch的詳細結構
    fmt.Printf("%+v\n", batteryAndTouch)
}
代碼說明如下:
  • 第 4 行,調用 genJsonData() 函數,獲得 []byte 類型的 JSON 數據。
  • 第 6 行,將 jsonData 的 []byte 類型的 JSON 數據轉換為字符串格式并打印輸出。
  • 第 9 行,構造匿名結構體,填充 Screen 結構和 HasTouchID 字段,第 12 行中的 {} 表示將結構體實例化。
  • 第 15 行,調用 json.Unmarshal,輸入完整的 JSON 數據(jsonData),將數據按第 9 行定義的結構體格式序列化到 screenAndTouch 中。
  • 第 18 行,打印輸出 screenAndTouch 中的詳細數據信息。
  • 第 21 行,構造匿名結構體,填充 Battery 結構和 HasTouchID 字段。
  • 第 27 行,調用 json.Unmarshal,輸入完整的 JSON 數據(jsonData),將數據按第 21 行定義的結構體格式序列化到 batteryAndTouch 中。
  • 第 30 行,打印輸出 batteryAndTouch 的詳細數據信息。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo