Maison > développement back-end > Golang > le corps du texte

Déterminer si le champ de type d'interface de struct est défini

PHPz
Libérer: 2024-02-09 18:27:08
avant
656 Les gens l'ont consulté

Déterminer si le champ de type dinterface de struct est défini

L'é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
   ...
}
Copier après la connexion

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{} }
Copier après la connexion

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
Copier après la connexion

À 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
    }
}
Copier après la connexion

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)
}
Copier après la connexion

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}
Copier après la connexion

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!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!