Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk Betul MarshalJSON() untuk Struktur Terbenam dengan Custom Marshaling?

Bagaimana untuk Betul MarshalJSON() untuk Struktur Terbenam dengan Custom Marshaling?

Linda Hamilton
Linda Hamiltonasal
2024-12-07 10:40:16865semak imbas

How to Correctly MarshalJSON() for Embedded Structs with Custom Marshaling?

Cara Idiomatik untuk Membenamkan Struct dengan Kaedah Custom MarshalJSON()

Masalah:

Bagaimana kita boleh mengekod struct dengan struct terbenam yang mempunyai kaedah MarshalJSON() tersuai? Output yang dijangkakan adalah untuk mengekalkan marshaling tersuai bagi struct terbenam sambil mengekod medan struct luar.

Contoh:

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

Apabila Orang yang terbenam struct mempunyai kaedah MarshalJSON() tersuai:

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.Name),
    })
}

Marshaling an Contoh pekerja terputus, mengakibatkan:

{"name": "BOB"}

Penyelesaian:

Daripada melaksanakan MarshalJSON() pada Orang, buat jenis Nama baharu yang melaksanakan MarshalJSON(). Kemudian, ubah suai Orang untuk menggunakan jenis Nama ini:

type Name string

func (n Name) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(string(n)),
    })
}

type Person struct {
    Name Name `json:"name"`
}

Ini membolehkan logik marshaling tersuai digunakan pada medan Nama sambil masih mengekodkan medan Pekerja seperti yang dijangkakan.

Penyelesaian Generik:

Untuk penyelesaian yang lebih generik, laksanakan MarshalJSON() pada struct luar. Walaupun kaedah pada jenis dalam dipromosikan kepada jenis luar, jenis luar kemudiannya boleh menyahmarshal hasilnya menjadi struktur generik seperti map[rentetan]antara muka{} dan menambah medannya sendiri.

Contoh:

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

func (e *Employee) MarshalJSON() ([]byte, error) {
    b, err := e.Person.MarshalJSON()
    if err != nil {
        return nil, err
    }

    var m map[string]interface{}
    if err := json.Unmarshal(b, &m); err != nil {
        return nil, err
    }

    m["jobRole"] = e.JobRole
    return json.Marshal(m)
}

Atas ialah kandungan terperinci Bagaimana untuk Betul MarshalJSON() untuk Struktur Terbenam dengan Custom Marshaling?. 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