Melalui Struktur Bersarang melalui Rujukan untuk Refleksi
Pengenalan
Pertimbangkan Pelanggan dan Kenalan berikut struktur data:
<code class="go">type Client struct { Id int Age int PrimaryContact Contact Name string } type Contact struct { Id int ClientId int IsPrimary bool Email string }</code>
Matlamat kami adalah untuk menggunakan refleksi untuk mengulangi semua medan struct Pelanggan, menetapkan nilai lalai untuk medan primitif dan secara rekursif menggunakan langkah yang sama pada mana-mana medan struct bersarang. Walau bagaimanapun, kami menghadapi panik "reflect.Value.Set menggunakan nilai tidak boleh ditangani" apabila cuba menetapkan nilai untuk medan PrimaryContact.
Melalui Rujukan
Masalah timbul kerana PrimaryContact diluluskan oleh nilai dan bukannya dengan rujukan. Untuk menyelesaikan masalah ini, kami mesti lulus PrimaryContact melalui rujukan. Untuk itu, kami menggunakan Value.Addr() untuk mendapatkan nilai penuding bagi medan struct.
Penyelesaian
Kod berikut menunjukkan cara menghantar PrimaryContact melalui rujukan:
<code class="go">func setDefaultValue(v reflect.Value) error { if v.Kind() != reflect.Ptr { return errors.New("Not a pointer value") } v = reflect.Indirect(v) // ... (same code as before) case reflect.Struct: for i := 0; i < v.NumField(); i++ { err := setDefaultValue(v.Field(i).Addr()) if err != nil { return err } } } return nil }</code>
Dengan menggunakan v.Field(i).Addr() untuk mendapatkan nilai penunjuk bagi setiap medan struct, kita boleh mengubah suai medan struct sebenar dan bukannya salinan.
Contoh
Untuk menggambarkan penyelesaiannya, mari kita pertimbangkan contoh Pelanggan berikut:
<code class="go">a := Client{}</code>
Selepas menggunakan fungsi SetDefault() kami, kami mendapat:
<code class="go">{Id:42 Age:42 PrimaryContact:{Id:42 ClientId:42 IsPrimary:true Email:Foo} Name:Foo}</code>
Ini menunjukkan bahawa medan struct PrimaryContact bersarang juga telah ditetapkan kepada nilai lalai.
Atas ialah kandungan terperinci Bagaimana untuk Melepasi Struktur Bersarang dengan Rujukan untuk Refleksi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!