81

エクスポートされていないフィールドが encoding/json に含まれない技術的な理由はありますか? そうでなく、恣意的な決定である場合、エクスポートされていない場合でも、追加のバックドアオプション (「+」など) を含めることができますか?

この機能を取得するためにクライアント コードをエクスポートする必要があることは、特に小文字でカプセル化が提供されている場合や、構造をマーシャリングする決定がそれらの設計よりもはるかに遅れている場合は、残念に感じられます。

人々はこれにどのように対処していますか?すべてをエクスポートするだけですか?

また、フィールド名をエクスポートすると、提案されたイディオムに従うことが難しくなりませんか。構造体 X にフィールド Y がある場合、アクセサ メソッド Y() を持つことはできないと思います。Y へのインターフェイス アクセスを提供したい場合は、getter の新しい名前を考え出す必要があります

4

3 に答える 3

108

技術的な理由があります。json ライブラリには、エクスポートされない限り、reflect を使用してフィールドを表示する機能がありません。パッケージは、そのパッケージ内の型のエクスポートされていないフィールドのみを表示できます

あなたの問題に対処するためにできることは、エクスポートされたフィールドでエクスポートされていない型を作成することです。Json は、問題なく渡された場合、エクスポートされていない型にアンマーシャリングされますが、API ドキュメントには表示されません。次に、エクスポートされていないタイプを埋め込むエクスポートされたタイプを作成できます。このエクスポートされた型には、json.Marshalerおよびjson.Unmarshalerインターフェイスを実装するメソッドが必要になります。

注: すべてのコードはテストされておらず、コンパイルすらできない可能性があります。

type jsonData struct {
    Field1 string
    Field2 string
}

type JsonData struct {
    jsonData
}

// Implement json.Unmarshaller
func (d *JsonData) UnmarshalJSON(b []byte) error {
    return json.Unmarshal(b, &d.jsonData)
}

// Getter
func (d *JsonData) Field1() string {
    return d.jsonData.Field1
}
于 2012-06-20T23:10:57.490 に答える
67

スティーブンの答えは完全です。余談ですが、json で小文字のキーだけが必要な場合は、次のようにキー名を手動で指定できます。

type Whatever struct {
    SomeField int `json:"some_field"`
}

このように、Whatever をマーシャリングすると、フィールド SomeField のキー「some_field」が生成されます (json に「SomeField」を含める代わりに)。

エクスポートされていないフィールドを保持することに固執している場合は、署名付きのメソッドを定義して json.Marshaler インターフェイスを実装することもできますMarshalJSON() ([]byte, error)。これを行う 1 つの方法は、次のように、エクスポートされていないフィールドのバージョンを単にエクスポートした構造体リテラルを使用することです。

type Whatever struct {
    someField int
}

func (w Whatever) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        SomeField int `json:"some_field"`
    }{
        SomeField: w.someField,
    })
}

これは少し面倒な場合があるため、必要に応じて a を使用することもできmap[string]interface{}ます。

func (w Whatever) MarshalJSON() ([]byte, error) {
    return json.Marshal(map[string]interface{}{
        "some_field": w.SomeField,
    })
}

ただし、マーシャリングinterface{}にはいくつかの注意点がありuint64、フロートへのマーシャリングなどを行うことができるため、精度が失われることに注意してください。(すべてのコードはテストされていません)

于 2012-06-20T23:31:05.553 に答える