Rumah >pembangunan bahagian belakang >Golang >Bagaimanakah Saya Boleh Mengesan dengan Amanah Jika Antara Muka Terbenam dalam Go Struct Mempunyai Pelaksanaan Fungsi Menggunakan Refleksi?

Bagaimanakah Saya Boleh Mengesan dengan Amanah Jika Antara Muka Terbenam dalam Go Struct Mempunyai Pelaksanaan Fungsi Menggunakan Refleksi?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-22 19:35:11422semak imbas

How Can I Reliably Detect If an Embedded Interface in a Go Struct Has a Function Implementation Using Reflection?

Pergi Refleksi dengan Antara Muka Terbenam dalam Struct

Mengesan Fungsi "Sebenar"

Pantulan Go pakej menyediakan akses kepada maklumat tentang jenis dan nilai semasa runtime. Ini boleh menjadi alat yang berkuasa, tetapi ia juga boleh mengelirukan apabila bekerja dengan antara muka terbenam dalam struct.

Pertimbangkan contoh berikut:

type A interface {
    Foo() string
}

type B struct {
    A
    bar string
}

Seperti yang anda perhatikan, Go tidak menguatkuasakan pelaksanaan antara muka terbenam pada masa penyusunan. Ini bermakna adalah mungkin untuk membenamkan antara muka dalam struct tanpa menyediakan pelaksanaan.

Menggunakan Refleksi untuk Mengakses Kaedah

Anda boleh menggunakan pakej refleksi untuk mendapatkan kaedah daripada antara muka terbenam struct, walaupun tiada pelaksanaan disediakan:

bType := reflect.TypeOf(B{})
bMeth, has := bType.MethodByName("Foo")
if has {
    fmt.Printf("HAS IT: %s\n", bMeth.Type.Kind())
    res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
    val := res[0].Interface()
    fmt.Println(val)
} else {
    fmt.Println("DOESNT HAS IT")
}

Walau bagaimanapun, jika antara muka terbenam tidak mempunyai pelaksanaan, kod ini boleh panik.

Mengesan Ketiadaan Pelaksanaan

Untuk mengesan sama ada antara muka terbenam tidak mempunyai pelaksanaan, anda boleh menyemak penuding kepada fungsi dalam jadual fungsi nilai antara muka tanpa nama:

b := B{}
bType := reflect.TypeOf(b)
bMeth, has := bType.MethodByName("Foo")
if has {
    bMethPtr := bMeth.Func.Pointer()
    if bMethPtr == 0 {
        fmt.Println("No implementation")
    } else {
        fmt.Println("Implementation found")
    }
} else {
    fmt.Println("Interface not embedded")
}

Jika penunjuk kepada fungsi ialah 0, tiada pelaksanaan. Jika tidak, pelaksanaan wujud.

Pendekatan Alternatif

Anda juga boleh menggunakan pendekatan yang lebih mudah:

if b.A != nil {
    b.Foo()
}

Jika antara muka terbenam ditetapkan hingga tiada, panggilan b.Foo() akan panik. Jika tidak, ia akan melaksanakan pelaksanaan (jika ada).

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengesan dengan Amanah Jika Antara Muka Terbenam dalam Go Struct Mempunyai Pelaksanaan Fungsi Menggunakan Refleksi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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