go - cómo acceder a claves y valores JSON profundamente anidados
(2)
Estoy escribiendo un cliente de websocket en Go. Recibo el siguiente JSON del servidor:
{"args":[{"time":"2013-05-21 16:57:17"}],"name":"send:time"}
Estoy intentando acceder al parámetro de time
, pero no puedo entender cómo llegar a un tipo de interfaz profundo:
package main;
import "encoding/json"
import "log"
func main() {
msg := `{"args":[{"time":"2013-05-21 16:56:16", "tzs":[{"name":"GMT"}]}],"name":"send:time"}`
u := map[string]interface{}{}
err := json.Unmarshal([]byte(msg), &u)
if err != nil {
panic(err)
}
args := u["args"]
log.Println( args[0]["time"] ) // invalid notation...
}
Que obviamente los errores, ya que la notación no es correcta:
invalid operation: args[0] (index of type interface {})
Simplemente no puedo encontrar una manera de profundizar en el mapa para obtener claves y valores profundamente anidados.
Una vez que pueda superar los valores dinámicos, me gustaría declarar estos mensajes. ¿Cómo escribiría una estructura de tipo para representar estructuras de datos tan complejas?
La interface{}
parte del map[string]interface{}
que decodifica coincidirá con el tipo de ese campo. Entonces en este caso:
args.([]interface{})[0].(map[string]interface{})["time"].(string)
debería devolver "2013-05-21 16:56:16"
Sin embargo, si conoce la estructura de JSON, debe intentar definir una estructura que coincida con esa estructura y desempate en eso. Ex:
type Time struct {
Time time.Time `json:"time"`
Timezone []TZStruct `json:"tzs"` // obv. you need to define TZStruct as well
Name string `json:"name"`
}
type TimeResponse struct {
Args []Time `json:"args"`
}
var t TimeResponse
json.Unmarshal(msg, &t)
Eso puede no ser perfecto, pero debería darte la idea
Puede considerar el paquete github.com/bitly/go-simplejson
Ver el documento: http://godoc.org/github.com/bitly/go-simplejson
Ejemplo:
time, err := json.Get("args").GetIndex(0).String("time")
if err != nil {
panic(err)
}
log.Println(time)