首頁 >後端開發 >Golang >如何可靠地檢測 Go 結構中的嵌入式介面是否具有使用反射的函數實作?

如何可靠地檢測 Go 結構中的嵌入式介面是否具有使用反射的函數實作?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-22 19:35:11398瀏覽

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

在結構體中使用嵌入式介面進行Go 反射

偵測「真實」函數

Go 的反射包提供在運行時存取有關類型和值的資訊。這可能是一個強大的工具,但在使用結構中的嵌入式介面時它也可能會令人困惑。

考慮以下範例:

type A interface {
    Foo() string
}

type B struct {
    A
    bar string
}

如您所觀察到的,Go 不在編譯時強制執行嵌入式介面。這意味著可以在不提供實現的情況下將介面嵌入到結構中。

使用反射存取方法

您可以使用反射包從struct的嵌入接口,即使沒有提供實現:

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")
}

但是,如果嵌入接口沒有提供

檢測是否存在實現

要偵測嵌入式介面是否沒有實現,您可以檢查指向該函數的指標匿名介面值的函數表:

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")
}

如果函數指標為0,則沒有實作。否則,存在實作。

替代方法

您也可以使用更簡單的方法:

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

如果設定了嵌入式介面如果設為nil,則b.Foo() 呼叫將會出現恐慌。否則,它將執行實作(如果有)。

以上是如何可靠地檢測 Go 結構中的嵌入式介面是否具有使用反射的函數實作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn