Maison > développement back-end > Golang > Comment transmettre des structures imbriquées par référence dans la réflexion et définir des valeurs par défaut de manière récursive ?

Comment transmettre des structures imbriquées par référence dans la réflexion et définir des valeurs par défaut de manière récursive ?

DDD
Libérer: 2024-10-24 02:22:29
original
451 Les gens l'ont consulté

How to Pass Nested Structures by Reference in Reflection and Set Default Values Recursively?

Passage de structures imbriquées par référence via réflexion

Le parcours et la modification de structures imbriquées par réflexion permettent une manipulation dynamique des données. Cependant, lorsque vous rencontrez un champ de structure qui est lui-même une structure, la définition de valeurs à l'aide de la réflexion peut conduire à une panique « reflect.Value.Set utilisant une valeur non adressable ».

Comprendre le problème

La racine du problème réside dans la façon dont la réflexion gère les structures imbriquées. Par défaut, les structures sont transmises par valeur, ce qui signifie que lorsque nous récupérons la valeur d'un champ de structure imbriqué pour modification, nous opérons sur une copie des données plutôt que sur l'original. Toute modification apportée n'affecte que la copie, pas la structure réelle.

Solution : passage par référence

Pour définir les valeurs de champ d'une structure imbriquée, il est nécessaire de passer comme un pointeur. Ceci peut être réalisé en utilisant la méthode Value.Addr(), qui renvoie un pointeur vers la valeur réelle de la structure.

Réglage de la valeur récursive par défaut

La récursion dans l'échantillon le code reflète la nécessité de parcourir tous les champs d'une structure et ses structures imbriquées. Pour définir les valeurs par défaut, nous appelons setDefaultValue sur la valeur du pointeur de chaque champ. Pour les types primitifs (int, string, bool), les valeurs par défaut sont codées en dur. Pour les structures imbriquées, setDefaultValue est appelée de manière récursive pour gérer leurs champs.

Exemple de travail

Considérez l'exemple de code suivant :

<code class="go">type Client struct {
    Id                int
    Age               int
    PrimaryContact    Contact
    Name              string
}

type Contact struct {
    Id        int
    ClientId  int
    IsPrimary bool
    Email     string
}

func SetDefault(s interface{}) error {
    return setDefaultValue(reflect.ValueOf(s))
}

func setDefaultValue(v reflect.Value) error {

    if v.Kind() != reflect.Ptr {
        return errors.New("Not a pointer value")
    }

    v = reflect.Indirect(v)
    switch v.Kind() {
        case reflect.Int:
            v.SetInt(42)
        case reflect.String:
            v.SetString("Foo")
        case reflect.Bool:
            v.SetBool(true)
        case reflect.Struct:
            // Iterate over the struct fields
            for i := 0; i < v.NumField(); i++ {
                err := setDefaultValue(v.Field(i).Addr())
                if err != nil {
                    return err
                }
            }       

        default:
            return errors.New("Unsupported kind: " + v.Kind().String())

    }

    return nil  
}


func main() {
    a := Client{}
    err := SetDefault(&a)
    if err != nil {
        fmt.Println("Error: ", err)
    } else {
        fmt.Printf("%+v\n", a)
    }
}</code>
Copier après la connexion

Sortie :

{Id:42 Age:42 PrimaryContact:{Id:42 ClientId:42 IsPrimary:true Email:Foo} Name:Foo}
Copier après la connexion

Cet exemple montre comment transmettre une structure imbriquée par référence par réflexion, en définissant les valeurs par défaut à l'aide de la récursivité.

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!

source:php
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