Mempertingkatkan Output JSON bagi Struktur Tidak Diketahui Secara Dinamik
Pengenalan
Dalam Go, adalah mungkin untuk meningkatkan Output JSON bagi struct yang diketahui dengan membenamkannya sebagai medan tanpa nama. Walau bagaimanapun, teknik ini hanya berfungsi dengan jenis tertentu. Artikel ini meneroka cara untuk melanjutkan fungsi ini kepada struct atau antara muka yang tidak diketahui.
Contoh
Pertimbangkan contoh berikut:
type example interface{} type Data struct { Name string } func printInterface(val interface{}) { example1 := struct { example Extra string }{ example: val, Extra: "text", } json.NewEncoder(os.Stdout).Encode(example1) } func main() { d := Data{Name: "name"} printInterface(&d) }
Kod ini mencetak JSON berikut :
{"example":{"Name":"name"},"Extra":"text"}
Perhatikan bagaimana medan "Nama" dibalut dengan yang tidak perlu objek "contoh".
Penyelesaian 1: Menjana Jenis Dinamik dengan Refleksi
Untuk mengelakkan objek "contoh", kita perlu menjana jenis dinamik pada masa jalan. Kami boleh menggunakan refleksi untuk mencipta jenis struct yang membenamkan antara muka yang tidak diketahui dan termasuk medan "Tambahan" tambahan kami.
func printInterface(val interface{}) { t2 := reflect.StructOf([]reflect.StructField{ { Name: "X", Anonymous: true, Type: reflect.TypeOf(val), }, { Name: "Extra", Type: reflect.TypeOf(""), }, }) v2 := reflect.New(t2).Elem() v2.Field(0).Set(reflect.ValueOf(val)) v2.FieldByName("Extra").SetString("text") json.NewEncoder(os.Stdout).Encode(v2.Interface()) }
Dengan perubahan ini, output menjadi:
{"Name":"name","Extra":"text"}
Penyelesaian 2: Marshaling dan Unmarshalling
Pendekatan alternatif adalah untuk menyusun antara muka, unmarshal menjadi peta, tambah medan tambahan, dan kemudian marshal sekali lagi:
func printInterface(val interface{}) error { data, err := json.Marshal(val) if err != nil { return err } v2 := map[string]interface{}{} if err := json.Unmarshal(data, &v2); err != nil { return err } v2["Extra"] = "text" return json.NewEncoder(os.Stdout).Encode(v2) }
Kaedah ini menghasilkan output yang sama seperti pendekatan jenis dinamik.
Kesimpulan
Kedua-duanya penyelesaian yang dibentangkan di sini membolehkan pelanjutan output JSON dengan medan sewenang-wenangnya untuk struktur atau antara muka yang tidak diketahui. Pendekatan berasaskan refleksi menyediakan penyelesaian jenis selamat, manakala teknik marshaling dan unmarshaling adalah lebih mudah tetapi berpotensi lebih perlahan. Pilihan kaedah bergantung pada keperluan khusus aplikasi.
Atas ialah kandungan terperinci Bagaimana untuk Menambah Medan secara Dinamik ke Output JSON daripada Unknown Go Structs?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!