4

JSON データを柔軟にデコードするための型を指定する必要があります。つまり、型を実行時に指定する必要があります。

このスニペットを検討してください: http://play.golang.org/p/F-Jy4ufMPz

s := `{"b":[{"x":9},{"x":4}]}`

var a struct {
  B []interface{}
}
err := json.Unmarshal([]byte(s), &a)
if err != nil {
  panic(err)
}

fmt.Println(a)

を生成し{[map[x:9] map[x:4]]}ます。[]interface{}コンパイル時に指定せずに、ではなく特定の (構造体) 型の配列にデコードしたい。

前もって配列を作成しなくても、それはどういうわけか可能ですか? (返品数は不明)

今考えられる唯一の方法は、返されたマップを後で再度エンコードし、それらを指定された型にデコードすることです。これにより、不要な処理オーバーヘッドが発生します。

4

1 に答える 1

5

コンパイル時に指定しない場合でも、どこかに指定する必要があります。

Json データを取得する前に指定した場合は、単純に switch ケースを実行して、目的のオブジェクトにアンマーシャリングすることができます。

Json データ内で指定されている場合、json.RawMessage適切な構造体のタイプを決定した後、「柔軟な」部分を にマーシャリングして処理できます。

package main

import (
    "encoding/json"
    "fmt"
)

var s = `{"type":"structx", "data":{"x":9,"xstring":"This is structX"}}`

type JsonStruct struct {
    Type string
    Data json.RawMessage
}

type StructX struct {
    X       float64
    Xstring string
}

type StructY struct {
    Y bool
}

func main() {
    var a *JsonStruct
    err := json.Unmarshal([]byte(s), &a)
    if err != nil {
        panic(err)
    }

    switch a.Type {
    case "structx":
        // We Unmashal the RawMessage part into a StructX
        var s *StructX
        json.Unmarshal([]byte(a.Data), &s)
        if err != nil {
            panic(err)
        }
        fmt.Println(s)
    case "structy":
        // Do the same but for structY
    }
}

遊び場

于 2013-10-30T20:19:27.247 に答える