web-dev-qa-db-ja.com

json.Unmarshalネストされたオブジェクトを文字列または[]バイトに

ネストされたオブジェクトが解析されず、stringまたは[]byteとして扱われるように、いくつかのjsonをアンマーシャリングしようとしています。

だから私は以下を取得したいと思います:

{
    "id"  : 15,
    "foo" : { "foo": 123, "bar": "baz" }
}

マーシャリングされていない:

type Bar struct {
    Id  int64  `json:"id"`
    Foo []byte `json:"foo"`
}

次のエラーが発生します。

json: cannot unmarshal object into Go value of type []uint8

遊び場デモ

19
Ilia Choly

あなたが探しているのは RawMessageencoding/jsonパッケージのタイプだと思います。

ドキュメントには次のように記載されています。

タイプRawMessage [] byte

RawMessageは、生のエンコードされたJSONオブジェクトです。 MarshalerとUnmarshalerを実装し、JSONデコードを遅らせたりJSONエンコーディングを事前計算したりするために使用できます。

RawMessageの使用例を次に示します。

package main

import (
    "encoding/json"
    "fmt"
)

var jsonStr = []byte(`{
    "id"  : 15,
    "foo" : { "foo": 123, "bar": "baz" }
}`)

type Bar struct {
    Id  int64           `json:"id"`
    Foo json.RawMessage `json:"foo"`
}

func main() {
    var bar Bar

    err := json.Unmarshal(jsonStr, &bar)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", bar)
}

出力:

{Id:15 Foo:[123 32 34102111111 34 58 32 49 50 51 44 32 34 98 97114 34 58 32 34 98 97122 34 32125]}

遊び場

28
ANisus

Fooタイプはmap [string] stringなので、Fooを正しく定義します。

type Bar struct {
    id int64
    Foo map[string]string
}

それがうまくいくと思う

3
gigatropolis

Unmarshalerインターフェースを実装する型を定義すると、解析中の[]byteにアクセスできます。

type Prefs []byte

func (p *Prefs) UnmarshalJSON(b []byte) error {
    *p = make(Prefs, len(b))
    copy(*p, b)
    return nil
}

遊び場デモ

2
Ilia Choly