Maison >développement back-end >Golang >Comment puis-je détecter de manière fiable si une interface intégrée dans une structure Go a une implémentation de fonction utilisant Reflection ?
Go Reflection avec interface intégrée dans Struct
Détection des fonctions "réelles"
La réflexion de Go Le package donne accès aux informations sur les types et les valeurs au moment de l’exécution. Cela peut être un outil puissant, mais il peut également prêter à confusion lorsque vous travaillez avec des interfaces intégrées dans des structures.
Considérez l'exemple suivant :
type A interface { Foo() string } type B struct { A bar string }
Comme vous l'avez observé, Go ne appliquer l'implémentation de l'interface intégrée au moment de la compilation. Cela signifie qu'il est possible d'intégrer une interface dans une structure sans fournir d'implémentation.
Utiliser Reflection pour accéder aux méthodes
Vous pouvez utiliser le package de réflexion pour obtenir des méthodes à partir d'un l'interface embarquée de struct, même si aucune implémentation n'est fournie :
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") }
Cependant, si l'interface embarquée n'a pas d'implémentation, ce code peut panique.
Détection de l'absence d'une implémentation
Pour détecter si une interface embarquée n'a pas d'implémentation, vous pouvez vérifier le pointeur vers la fonction dans la table des fonctions du valeur d'interface anonyme :
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") }
Si le pointeur vers la fonction est 0, il n'y a pas d'implémentation. Sinon, une implémentation existe.
Approche alternative
Vous pouvez également utiliser une approche plus simpliste :
if b.A != nil { b.Foo() }
Si l'interface intégrée est définie à zéro, l'appel b.Foo() va paniquer. Sinon, il exécutera l'implémentation (le cas échéant).
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!