Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk Mengekalkan Marshalling Tersuai dalam Struktur Terbenam Go?
Memelihara Marshalling Tersuai untuk Struktur Terbenam
Dalam Go, membenamkan satu struct ke yang lain ialah cara biasa untuk mewarisi kefungsian. Walau bagaimanapun, apabila struct terbenam mempunyai kaedah MarshalJSON() tersuai, isu boleh timbul. Artikel ini meneroka penyelesaian kepada cabaran ini, memastikan bahawa struct luar boleh menyusun medannya secara normal sambil masih memanfaatkan marshalling tersuai bagi struct terbenam.
Pertimbangkan struct berikut:
type Person struct { Name string `json:"name"` } type Employee struct { *Person JobRole string `json:"jobRole"` }
Biasanya, menggabungkan Pekerja kepada JSON akan menghasilkan yang diharapkan output:
p := Person{"Bob"} e := Employee{&p, "Sales"} output, _ := json.Marshal(e) fmt.Printf("%s\n", string(output)) // Output: {"name":"Bob","jobRole":"Sales"}
Walau bagaimanapun, memperkenalkan kaedah MarshalJSON() tersuai untuk struct Person terbenam mengubah tingkah laku ini:
func (p *Person) MarshalJSON() ([]byte, error) { return json.Marshal(struct{ Name string `json:"name"` }{Name: strings.ToUpper(p.Name)}) }
Sekarang, marshalling Employee hanya menghasilkan nama huruf besar:
output, _ := json.Marshal(e) fmt.Printf("%s\n", string(output)) // Output: {"name":"BOB"}
Untuk menyelesaikan masalah ini, seseorang mungkin cuba menambah kaedah MarshalJSON() pada struktur Pekerja luar. Walau bagaimanapun, pendekatan ini memerlukan pengetahuan tentang marshalling tersuai jenis terbenam, yang mungkin tidak selalu praktikal.
Penyelesaian yang lebih generik melibatkan pelaksanaan terus MarshalJSON() pada jenis luar:
// Note: not on Person func (e *Employee) MarshalJSON() ([]byte, error) { inner, err := json.MarshalIndent((*e.Person).(*Person), "", " ") if err != nil { return nil, err } b := []byte(strings.Replace(string(inner), "}", "}", -1)) b = append(b, []byte(`,"jobRole":"`+e.JobRole+`"}`)...) return b, nil }
Pendekatan ini memanggil kaedah MarshalJSON() struct terbenam, menukar hasilnya kepada peta dan menambah medan struct luar untuk menghasilkan output JSON yang dikehendaki. Ambil perhatian bahawa ia tidak memanipulasi marshalling tersuai struct terbenam.
Sebagai alternatif, seseorang boleh menggunakan pendekatan berasaskan refleksi:
func (e *Employee) MarshalJSON() ([]byte, error) { v := reflect.ValueOf(e).Elem() vf := v.FieldByName("Person") tmp, err := json.MarshalIndent(vf.Interface(), "", " ") if err != nil { return nil, err } return []byte(strings.Replace(string(tmp), "}", `,"jobRole":"`+e.JobRole+`"}`, -1)), nil }
Kaedah ini menggunakan refleksi untuk mengakses nilai dan medan struct terbenam , membolehkan marshalling tersuai tanpa bergantung pada pengetahuan struktur.
Dengan melaksanakan MarshalJSON() pada jenis luar, pendekatan ini memastikan bahawa kedua-dua medan struktur terbenam dan luar disusun dengan betul, mengekalkan output yang diingini.
Atas ialah kandungan terperinci Bagaimana untuk Mengekalkan Marshalling Tersuai dalam Struktur Terbenam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!