Go言語でのJSONデータの変換方法

Go言語の標準ライブラリであるencoding/jsonパッケージを使用することで、JSON形式へのシリアライズおよびデシリアライズが可能です。以下のルールに基づいてデータ構造を変換します。


bool → JSONのブーリアン
float64 → JSONの数値
string → JSONの文字列
[]interface{} → JSONの配列
map[string]interface{} → JSONのオブジェクト
nil → JSONのnull

ポインタが含まれる場合、その参照先の値に変換されます。また、チャネルや複素数、関数は有効なJSON形式に変換できません。未知のJSON構造に対しては、interface{}を受信コンテナとして使用できます。


type Device struct {
  Maker string
  // 無視するフィールド
  Model string `json:"-"` 
  // 空の場合は無視
  Cost float32 `json:"cost,omitempty"`
  // 別名指定可能
  HasBluetooth bool `json:"bluetooth,omitempty"`
  Parts []string
}

ストリームによる読み書きには以下を使用します。


func NewDecoder(r io.Reader) *Decoder
func NewEncoder(w io.Writer) *Encoder

サンプルコード


package main

import (
	"fmt"
	"encoding/json"
)

type Device struct {
  Maker string
  Model string
  Cost float64
  HasBluetooth bool `json:"bluetooth"`
  Parts []string
}

func main() {
  parts := []string{"RTX3090", "AMD Ryzen 9 5950X", "64GB RAM", "DDR4-3600", "1TB NVMe"}
  device := Device{
    Maker: "Dell",
    Model: "Precision XPS",
    Cost: 0,
    HasBluetooth: false,
    Parts: parts,
  }
  
  if jsonData, err := json.Marshal(device); err != nil {
    return
  } else {
    fmt.Println(string(jsonData))
    
    var gadget Device
    data := []byte(`{
      "Maker": "Dell",
      "Model": "Precision XPS",
      "Cost": 0.0,
      "bluetooth": true,
      "Parts": ["Intel i9-11900K", "NVIDIA RTX 3080"]
    }`)
    
    if err := json.Unmarshal(data, &gadget); err == nil {
      fmt.Println(gadget)
    } else {
      fmt.Println(err)
    }
    
    var unknownJson interface{}
    if err := json.Unmarshal(data, &unknownJson); err == nil {
      unknownMap, ok := unknownJson.(map[string]interface{})
      if ok {
        for key, value := range unknownMap {
          switch valueType := value.(type) {
            case string:
              fmt.Printf("String: %s = %s\n", key, valueType)
            case float64:
              fmt.Printf("Float: %s = %.2f\n", key, valueType)
            case bool:
              fmt.Printf("Bool: %s = %t\n", key, valueType)
            case []interface{}:
              fmt.Printf("%s is an array:\n", key)
              for index, item := range valueType {
                fmt.Printf("%d: %v\n", index, item)
              }
            default:
              fmt.Printf("Unknown type: %s\n", key)
          }
        }
      }
    }
  }
}

タグ: Go JSON encoding/json データ変換 シリアライズ

6月19日 22:03 投稿