在結構體中使用嵌入式介面進行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中文網其他相關文章!