首頁 >後端開發 >Golang >如何在 Go 中有效地解組不一致的 JSON 欄位(有時是字串,有時是字串陣列)?

如何在 Go 中有效地解組不一致的 JSON 欄位(有時是字串,有時是字串陣列)?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-22 01:21:15462瀏覽

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

不一致的JSON 欄位處理:解組為字串或陣列

使用表現出不一致的JSON 資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時,解組可能有資料時挑戰性類型可以不同的字段,例如字串或字串陣列。本文解決了這個問題並提供了實用的解決方案。

問題

考慮以下JSON 結構,其中「display_name」欄位是字串或字串陣列:

{
    "date": "30 Apr",
    "display_name": "Mr Smith"
},
{
    "date": "30 Apr",
    "display_name": ["Mr Smith", "Mr Jones"],
}

嘗試使用以下Go結構解組此數據將導致錯誤:

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, "&&")
    }
}

對於如果資料模型中多次出現這種不一致的字段,可以使用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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn