4

JSON を効率的にエンコードしたい構造体があります。

type MyStruct struct {
    *Meta
    Contents []interface{}
}

type Meta struct {
    Id int
}

構造体には、既知の形式のメタ データと未知の形式のコンテンツが含まれています。コンテンツ リストは実行時に入力されるため、それらを実際に制御することはできません。Go のマーシャリング速度を向上させるために、Meta 構造体に Marshaller インターフェイスを実装したいと考えています。Marshaller インターフェイスは次のようになります。

type Marshaler interface {
        MarshalJSON() ([]byte, error)
}

Meta 構造体はここに示すほど単純ではないことに注意してください。Meta 構造体に Marshaler インターフェイスを実装しようとしましたが、MyStruct を JSON マーシャリングすると、結果は Meta マーシャリング インターフェイスによって返された結果のみになるようです。

私の質問は次のとおりです: 構造体を JSON マーシャリングするにはどうすればよいですか? 構造体には、独自の JSON マーシャラーを持つ埋め込み構造体と、それを持たない別の構造体が含まれています。

4

1 に答える 1

4

MarshalJSON匿名フィールドのメソッド*Metaが に昇格されるためMyStructencoding/jsonパッケージは MyStruct がマーシャリングされるときにそのメソッドを使用します。

できることは、インターフェイスを実装する代わりに、MetaMarshallerのように MyStruct にインターフェイスを実装することです。

package main

import (
    "fmt"
    "encoding/json"
    "strconv"
)

type MyStruct struct {
    *Meta
    Contents []interface{}
}

type Meta struct {
    Id int
}

func (m *MyStruct) MarshalJSON() ([]byte, error) {
    // Here you do the marshalling of Meta
    meta := `"Id":` + strconv.Itoa(m.Meta.Id)

    // Manually calling Marshal for Contents
    cont, err := json.Marshal(m.Contents)
    if err != nil {
        return nil, err
    }

    // Stitching it all together
    return []byte(`{` + meta + `,"Contents":` + string(cont) + `}`), nil
}


func main() {
    str := &MyStruct{&Meta{Id:42}, []interface{}{"MyForm", 12}}

    o, err := json.Marshal(str)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(o))
}

{"Id":42,"内容":["マイフォーム",12]}

遊び場

于 2013-08-30T08:39:01.100 に答える