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)
}
}
}
}
}
}