Bagaimana untuk Mendapatkan Alamat Medan dalam Struktur Bersarang Menggunakan Refleksi?

Susan Sarandon
Lepaskan: 2024-10-30 14:08:03
asal
647 orang telah melayarinya

How to Obtain Field Addresses in Nested Structures Using Reflection?

Mendapatkan Alamat Medan dalam Struktur Bersarang Menggunakan Refleksi

Dalam senario ini, anda ingin merentasi dan memeriksa struktur bersarang dan mendapatkan alamat bukan -medan penunjuk di dalamnya. Dengan menggunakan refleksi, anda mempunyai fungsi yang berulang melalui medan tetapi menghadapi kesukaran mendapatkan alamat memori medan bukan penuding yang terletak dalam substruktur terbenam.

Untuk membetulkan isu ini, adalah penting untuk ambil perhatian bahawa valueField.Interface() tidak tidak memberikan hasil yang dijangkakan kerana ia mengembalikan nilai sebenar yang disimpan dalam medan, yang tidak sah apabila bekerja dengan jenis bukan penuding.

Penyelesaian terletak pada mengubah suai fungsi InspectStructV untuk menerima reflect.Value dan bukannya antara muka{}. Ini membolehkan anda memanipulasi objek pantulan secara langsung dan mendapatkan semula alamat medan. Selain itu, apabila memanggil InspectStructV secara rekursif untuk medan struct, valueField, yang sebelum ini memegang nilai antara muka, kini terus menunjuk kepada nilai pantulan untuk struktur bersarang, memastikan alamat itu boleh diambil dengan betul.

Berikut ialah kod yang disemak semula coretan:

<code class="go">func InspectStructV(val reflect.Value) {
    if val.Kind() == reflect.Interface && !val.IsNil() {
        elm := val.Elem()
        if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
            val = elm
        }
    }
    if val.Kind() == reflect.Ptr {
        val = val.Elem()
    }

    for i := 0; i < val.NumField(); i++ {
        valueField := val.Field(i)
        typeField := val.Type().Field(i)
        address := "not-addressable"

        if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
            elm := valueField.Elem()
            if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
                valueField = elm
            }
        }

        if valueField.Kind() == reflect.Ptr {
            valueField = valueField.Elem()
        }

        if valueField.CanAddr() {
            address = fmt.Sprintf("0x%X", valueField.Addr().Pointer())
        }

        fmt.Printf("Field Name: %s,\t Field Value: %v,\t Address: %v\t, Field type: %v\t, Field kind: %v\n", typeField.Name,
            valueField.Interface(), address, typeField.Type, valueField.Kind())

        if valueField.Kind() == reflect.Struct {
            InspectStructV(valueField)
        }
    }
}

func InspectStruct(v interface{}) {
    InspectStructV(reflect.ValueOf(v))
}</code>
Salin selepas log masuk

Dengan membuat perubahan ini, anda akan dapat berjaya mendapatkan semula alamat memori medan bukan penuding walaupun ia berada dalam struktur bersarang.

Atas ialah kandungan terperinci Bagaimana untuk Mendapatkan Alamat Medan dalam Struktur Bersarang Menggunakan Refleksi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan