2013-06-12 26 views
8

次のJSONビットがあるので、「トークン」の下の「$ t」値を引き出したいと思います。 Goコードを続行してください...golang:地図内の地図のデータにすばやくアクセスする

{ 
    "@encoding": "iso-8859-1", 
    "@version": "1.0", 
    "service": { 
    "auth": { 
     "expiresString": { 
     "$t": "2013-06-12T01:15:28Z" 
     }, 
     "token": { 
     "$t": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
     }, 
     "expires": { 
     "$t": "1370999728" 
     }, 
     "key": { 
     "$t": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
     } 
    } 
} 

次のコードは、jsonをインターフェイスに非整列化するスニペットです。それから、私は "トークン"の "$ t"値まで下がって行きます。このアプローチはうまくいくが、醜い。

私の質問:各マップをインターフェースに変換するよりも、その値にアクセスする方が速いのですか?私は非常に新しく、インターフェイスやマップの便利な機能の多くを認識していません。

var f interface{} 
jerr := json.Unmarshal(body, &f) 
m := f.(map[string]interface{}) 
ser := m["service"].(map[string]interface{}) 
a := ser["auth"].(map[string]interface{}) 
tok := a["token"].(map[string]interface{}) 
token := tok["$t"] 
fmt.Fprintf(w, "Token: %v\n", token) 

ありがとうございます!

答えて

11

これが唯一の値であれば、データへのパスを定義する匿名のstructを使用してください。

var m = new(struct{Service struct{Auth struct{Token map[string]string}}}) 

var err = json.Unmarshal([]byte(data), &m) 

fmt.Println(m.Service.Auth.Token["$t"], err) 

DEMO:http://play.golang.org/p/ZdKTzM5i57


代わりに、我々は別の構造体を使用することができますが、私たちがエイリアスするフィールドタグを提供する必要があると思い最も内側のデータのためのmapを使用します名。

var m = new(struct{Service struct{Auth struct{Token struct{T string `json:"$t"`}}}}) 

var err = json.Unmarshal([]byte(data), &m) 

fmt.Println(m.Service.Auth.Token.T, err) 

DEMO:http://play.golang.org/p/NQTpaUvanx

+0

を見ます。両方のバージョンを含めてくれてありがとう。 – turnerd18

+0

ようこそ。 –

6

ORあなたは私たちのシチューパッケージからobjects.Mapを使用することができ、それはあなたがマップのためのアクセサをドット与える:

objects.Map(data).Get("service.auth.token") 

は非常にいいhttp://godoc.org/github.com/stretchr/stew/objects