Kebolehcapaian Medan Peribadi Merentasi Pakej
Pertimbangkan senario di mana struct yang ditakrifkan dalam satu pakej (mis., foo) mengandungi medan peribadi dan pakej lain (cth., bar) memerlukan akses kepada mereka. Malangnya, enkapsulasi peringkat pakej Go melarang akses terus ke medan peribadi daripada pakej luaran.
Walau bagaimanapun, terdapat cara terhad untuk mengakses medan peribadi ini, walaupun dengan kaveat tertentu:
Menggunakan Refleksi (Pergi < 1.7)
Sebelum Pergi 1.7, adalah mungkin untuk membaca medan persendirian menggunakan refleksi:
package bar import "../foo" import "fmt" import "reflect" func read_foo(f *foo.Foo) { v := reflect.ValueOf(*f) y := v.FieldByName("y") fmt.Println(y.Interface()) }
Pendekatan ini membenarkan pengambilan semula nilai medan persendirian tetapi bukan pengubahsuaiannya.
Memanipulasi Memori (Go > = 1.7)
Dalam Go versi 1.7 dan ke atas, kaedah yang kurang diingini melibatkan memanipulasi ingatan secara langsung menggunakan penunjuk yang tidak selamat. Dengan memajukan penuding memori berdasarkan saiz medan dan mengimbangi, adalah mungkin untuk mengakses medan peribadi:
package bar import "../foo" import "unsafe" func change_foo(f *foo.Foo) { ptrTof := unsafe.Pointer(f) ptrTof = unsafe.Pointer(uintptr(ptrTof) + uintptr(8)) // Advance by the size of int ptrToy := (**foo.Foo)(ptrTof) *ptrToy = nil }
Kaedah ini sangat tidak digalakkan kerana sifatnya yang tidak mudah alih dan berpotensi untuk kerosakan data.
Penyelesaian Alternatif
Daripada mengakses medan peribadi secara langsung, terdapat yang lebih sesuai pilihan:
Ingat, tujuan enkapsulasi adalah untuk mengekalkan integriti data dan mengelakkan pengubahsuaian yang tidak diingini. Jika keperluan untuk mengakses medan persendirian timbul, pertimbangkan dengan teliti sama ada terdapat alternatif yang lebih sesuai.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengakses Medan Peribadi dalam Merentas Pakej Berbeza?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!