ホームページ > バックエンド開発 > Golang > Go で文字列である場合もあれば文字列の配列である場合もある、一貫性のない JSON フィールドを効率的にアンマーシャリングするにはどうすればよいですか?

Go で文字列である場合もあれば文字列の配列である場合もある、一貫性のない JSON フィールドを効率的にアンマーシャリングするにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2024-12-22 01:21:15
オリジナル
418 人が閲覧しました

How Can I Efficiently Unmarshal Inconsistent JSON Fields That Are Sometimes Strings and Sometimes Arrays of Strings in Go?

一貫性のない JSON フィールドの処理: 文字列または配列としてのアンマーシャリング

矛盾を示す JSON データを扱う場合、アンマーシャリングが困難になる場合があります文字列または文字列の配列など、型が異なるフィールド。この記事では、この問題に対処し、実用的な解決策を示します。

問題

「display_name」フィールドが文字列または文字列の配列である次の JSON 構造を考えてみましょう。 :

{
    "date": "30 Apr",
    "display_name": "Mr Smith"
},
{
    "date": "30 Apr",
    "display_name": ["Mr Smith", "Mr Jones"],
}
ログイン後にコピー

次の Go 構造を使用してこのデータをアンマーシャルしようとすると、 error:

type MyListItem struct {
    Date  string `json:"date"`
    DisplayName       string `json:"display_name"`
}

type MyListings struct {
    CLItems []MyListItem `json:"myitems"`
}
ログイン後にコピー

解決策

この課題を克服するには、さまざまなフィールド データのキャプチャを可能にする json.RawMessage の多用途性を利用できます。さらに、「-」フィールド名を使用してデコーダから「DisplayName」フィールドを非表示にし、最上位の JSON がデコードされた後にアプリケーションがフィールドに値を設定できるようにします。

変更された Go 構造

type MyListItem struct {
    Date           string          `json:"date"`
    RawDisplayName json.RawMessage `json:"display_name"`
    DisplayName    []string        `json:"-"`
}
ログイン後にコピー

アンマーシャリングプロセス

トップレベル JSON のアンマーシャリング:

var li MyListItem
if err := json.Unmarshal(data, &li); err != nil {
    // handle error
}
ログイン後にコピー

生データのタイプに基づいて "display_name" フィールドを再構築:

if len(li.RawDisplayName) > 0 {
    switch li.RawDisplayName[0] {
    case '"':
        if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil {
            // handle error
        }
    case '[':
        var s []string
        if err := json.Unmarshal(li.RawDisplayName, &s); err != nil {
            // handle error
        }
        // Join arrays with "&&" per OP's comment on the question.
        li.DisplayName = strings.Join(s, "&&")
    }
}
ログイン後にコピー

Forデータ モデル内でこの一貫性のないフィールドが複数回発生すること、json.Unmarshaler インターフェイスのカスタム タイプと実装ロジックをカプセル化するために使用できます。

カスタム アンマーシャラー

type multiString string

func (ms *multiString) UnmarshalJSON(data []byte) error {
    if len(data) > 0 {
        switch data[0] {
        case '"':
            var s string
            if err := json.Unmarshal(data, &s); err != nil {
                return err
            }
            *ms = multiString(s)
        case '[':
            var s []string
            if err := json.Unmarshal(data, &s); err != nil {
                return err
            }
            *ms = multiString(strings.Join(s, "&&"))
        }
    }
    return nil
}
ログイン後にコピー

カスタム アンマーシャラーとの使用

type MyListItem struct {
    Date        string      `json:"date"`
    DisplayName multiString `json:"display_name"`
}

type MyListings struct {
    CLItems []MyListItem `json:"myitems"`
}

var listings MyListings
if err := json.Unmarshal([]byte(data), &listings); err != nil {
    log.Fatal(err)
}
ログイン後にコピー

これらのソリューションは、一貫性のない JSON フィールドを効率的に処理するための包括的なアプローチを提供し、柔軟なマッピングを可能にします。データ構造と JSON 表現の間。

以上がGo で文字列である場合もあれば文字列の配列である場合もある、一貫性のない JSON フィールドを効率的にアンマーシャリングするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート