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)
}
型は以下の通りになります。