JSON文字列をデコードする

ツイート このエントリーをはてなブックマークに追加
1つ上へ / ブログトップへ

io.Readerであれば、文字列でなくてもオブジェクトにデコードできるようです。

package main

import (
        "encoding/json"
        "fmt"
        "strings"
)

func main() {
        s := "{\"name\":\"fkm\",\"age\":29,\"lang\":[\"Java\",\"Go\"]}"
        r := strings.NewReader(s)
        doc := json.NewDecoder(r)
        var obj map[string]interface{}
        doc.Decode(&obj)
        v := obj["name"]
        if name, ok := v.(string); ok {
                fmt.Printf("name is %s\n", name)
        }
        v = obj["lang"]
        if array, ok := v.([]interface{}); ok {
                fmt.Printf("array\n")
                dumpArray(array)
        }
}

func dumpArray(arr []interface{}) {
        for _, item := range arr {
                if val, ok := item.(string); ok {
                        fmt.Printf("value=%s\n", val)
                }
        }
}

重要なのはこの3行です。

doc := json.NewDecoder(r)
var obj map[string]interface{}
doc.Decode(&obj)

変数objは、他の言語で言うところの汎用的なJSONObjectを表します。値の部分には何が入っているかまちまちなので、interface{}型にしています。objの型を別のものにした場合は別エントリーで紹介します。

実際に値を取り出す時は、type assertionを使ってチェックしつつ取り出します。

// この時点では、vはinterface{}型
v := obj["name"]
// vがstring型の時、nameに値が代入され、okがtrueになる。
if name, ok := v.(string); ok {
        fmt.Printf("name is %s\n", name)
}

型は以下の通りになります。

  • 値がboolの時は、v.(bool)
  • 値が数値の時は、v.(float64) intであってもfloat64で取得する点注意
  • 値がnullの時は、v.(nil)
  • 値がJSONObjectの時は、v.(mapinterface{})
  • 値がJSONArrayの時は、v.(interface{})
1つ上へ / ブログトップへ