Rumah >pembangunan bahagian belakang >Golang >Bagaimanakah Saya Boleh Menyahmarshal Medan JSON Tidak Konsisten Dengan Cekap Yang Kadang-kadang Rentetan dan Kadang-kadang Susunan Rentetan dalam Go?

Bagaimanakah Saya Boleh Menyahmarshal Medan JSON Tidak Konsisten Dengan Cekap Yang Kadang-kadang Rentetan dan Kadang-kadang Susunan Rentetan dalam Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-22 01:21:15459semak imbas

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

Pengendalian Medan JSON yang tidak konsisten: Unmarshaling as a String or Array

Apabila bekerja dengan data JSON yang menunjukkan ketidakkonsistenan, ia boleh mencabar untuk unmarshal medan yang boleh berbeza dalam jenis, seperti sama ada rentetan atau tatasusunan rentetan. Artikel ini menangani isu ini dan menyediakan penyelesaian praktikal.

Masalahnya

Pertimbangkan struktur JSON berikut di mana medan "display_name" ialah sama ada rentetan atau tatasusunan rentetan :

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

Percubaan untuk menyahmarshal data ini dengan struktur Go berikut akan mengakibatkan ralat:

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

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

Penyelesaian

Untuk mengatasi cabaran ini, seseorang boleh menggunakan kepelbagaian json.RawMessage, yang membolehkan penangkapan data medan yang berbeza-beza. Selain itu, nama medan "-" boleh digunakan untuk menyembunyikan medan "Nama Paparan" daripada penyahkod, membenarkan aplikasi mengisinya selepas JSON peringkat atas dinyahkodkan.

Struktur Go Diubahsuai

type MyListItem struct {
    Date           string          `json:"date"`
    RawDisplayName json.RawMessage `json:"display_name"`
    DisplayName    []string        `json:"-"`
}

Menyahmarshaling Proses

Menyahmarshall JSON peringkat atas:

var li MyListItem
if err := json.Unmarshal(data, &li); err != nil {
    // handle error
}

Membina semula medan "display_name" berdasarkan jenis data mentah:

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

Untuk berbilang kejadian medan tidak konsisten ini dalam model data, jenis tersuai dan pelaksanaan antara muka json.Unmarshaler boleh digunakan untuk merangkum logik.

Custom 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
}

Penggunaan dengan Custom Unmarshaler

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)
}

Penyelesaian ini menyediakan pendekatan komprehensif untuk mengendalikan medan JSON yang tidak konsisten dengan cekap, membolehkan pemetaan fleksibel antara data struktur dan perwakilan JSON.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Menyahmarshal Medan JSON Tidak Konsisten Dengan Cekap Yang Kadang-kadang Rentetan dan Kadang-kadang Susunan Rentetan dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn