


Déterminer si le champ de type d'interface de struct est défini
Feb 09, 2024 pm 06:27 PML'éditeur PHP Xiaoxin est là pour partager une astuce pour déterminer si le champ de type d'interface de struct est défini. Dans le langage Go, le type struct peut implémenter plusieurs interfaces. En déterminant si le champ type d'interface est défini, nous pouvons facilement déterminer si une structure implémente une interface spécifique. Cette technique est très pratique. Elle permet de déterminer avec précision le type d’objet dans le code et de le gérer en conséquence. Examinons ensuite la méthode de mise en œuvre spécifique !
Contenu de la question
Étant donné une structure dont les champs appartiennent au type d'interface :
type a interface { foo() } type b interface { bar() } type container struct { fielda a fieldb b ... }
Et les structures qui mettent en œuvre ces interfaces :
type a struct {} func (*a) foo() {} func newa() *a { return &a{} } type b struct {} func (*b) bar() {} func newb() *b { return &b{} }
Et le code qui crée l'instance container
sans définir explicitement tous les champs :
c := &container{} c.fielda = newa() // c.fieldb = newb() // <-- fieldb not explicitly set
À l'aide de la réflexion, comment puis-je détecter un champ qui n'est pas défini explicitement ?
Vérifiez la valeur de fieldb au moment de l'exécution, vscode rapporte volontiers la valeur comme nil
. De même, essayer d'appeler c.fieldb.bar() paniquera en raison d'un déréférencement de pointeur nul. Mais la réflexion ne vous permet pas de tester isnil, et iszero ne renvoie pas non plus vrai :
func validateContainer(c *container) { tC := reflect.TypeOf(*c) for i := 0; i < tC.NumField(); i++ { reflect.ValueOf(tC.Field(i)).IsNil() // panics reflect.ValueOf(tC.Field(i)).IsZero() // always false reflect.ValueOf(tC.Field(i)).IsValid() // always true } }
Solution
Tu devrais vérifier reflect.valueof(*c)
的字段,而不是 reflect.typeof(*c)
.
package main import ( "fmt" "reflect" ) func validatecontainer(c *container) { tc := reflect.typeof(*c) vc := reflect.valueof(*c) for i := 0; i < vc.numfield(); i++ { if f := vc.field(i); f.kind() == reflect.interface { fmt.printf("%v: isnil: %v, iszero: %v, isvalid: %v\n", tc.field(i).name, f.isnil(), f.iszero(), f.isvalid(), ) } } // tc.field(i) returns a reflect.structfield that describes the field. // it's not the field itself. fmt.printf("%#v\n", reflect.valueof(tc.field(0))) } type a interface{ foo() } type b interface{ bar() } type container struct { fielda a fieldb b } type a struct{} func (*a) foo() {} func newa() *a { return &a{} } func main() { c := &container{} c.fielda = newa() validatecontainer(c) }
Sortie :
FieldA: IsNil: false, isZero: false, IsValid: true FieldB: IsNil: true, isZero: true, IsValid: true reflect.StructField{Name:"FieldA", PkgPath:"", Type:(*reflect.rtype)(0x48de20), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}
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!

Article chaud

Outils chauds Tags

Article chaud

Tags d'article chaud

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Comment utiliser la réflexion pour accéder aux champs et méthodes privés dans Golang

Conseils pour créer dynamiquement de nouvelles fonctions dans les fonctions Golang

La différence entre les tests de performances et les tests unitaires en langage Go

À quels pièges devons-nous prêter attention lors de la conception de systèmes distribués avec la technologie Golang ?

Bibliothèques technologiques Golang et outils utilisés dans l'apprentissage automatique

L'évolution de la convention de dénomination des fonctions Golang

Le rôle de la technologie Golang dans le développement de l'IoT mobile

Les paramètres de variables Golang peuvent-ils être utilisés pour les valeurs de retour de fonction ?
