Maison > développement back-end > Golang > Quelle est la bonne façon d'attribuer conditionnellement plusieurs propriétés à une structure

Quelle est la bonne façon d'attribuer conditionnellement plusieurs propriétés à une structure

WBOY
Libérer: 2024-02-06 08:05:11
avant
666 Les gens l'ont consulté

Quelle est la bonne façon dattribuer conditionnellement plusieurs propriétés à une structure

Contenu de la question

Je développe une fonction d'analyseur pour la requête graphql de be que j'ai écrite en go. Dans l'analyseur, j'ai des données utilisateur que je souhaite mettre à jour, en utilisant une valeur d'entrée qui contient plusieurs propriétés de mise à jour possibles.

En javascript cela peut être fait rapidement avec la déstructuration (pseudo) :

const mergedobj = {...oldprops, ...newprops}

Actuellement, ma fonction d'analyseur ressemble à ceci (en utilisant gqlgen comme analyseur graphql go) :

func (r *mutationResolver) ModifyUser(ctx context.Context, input *model.ModifyUserInput) (*model.User, error) {
    id := input.ID
    us, ok := r.Resolver.UserStore[id]
    if !ok {
        return nil, fmt.Errorf("not found")
    }

    if input.FirstName != nil {
        us.FirstName = *input.FirstName
    }

    if input.LastName != nil {
        us.LastName = *input.LastName
    }

    if input.ProfileImage != nil {
        us.ProfileImage = input.ProfileImage
    }

    if input.Password != nil {
        us.Password = *input.Password
    }

    if input.Email != nil {
        us.Email = *input.Email
    }

    if input.InTomorrow != nil {
        us.InTomorrow = input.InTomorrow
    }

    if input.DefaultDaysIn != nil {
        us.DefaultDaysIn = input.DefaultDaysIn
    }

    r.Resolver.UserStore[id] = us

    return &us, nil
}
Copier après la connexion

Cela semble si facile. Est-il judicieux de parcourir les clés de structure dans ce cas ? Ou y a-t-il un autre modèle qui me manque ?


Bonne réponse


Utiliser des fonctions pour réduire le passe-partout :

func mergef[t any](a, b *t) {
    if b != nil {
        *a = *b
    }
}

...
mergef(&us.firstname, input.firstname)
mergef(&us.lastname, input.lastname)
...
Copier après la connexion

Utilisez le package de réflexion pour réduire davantage de passe-partout :

// merge sets fields in struct pointed to by d to 
// dereferenced fields in struct pointed to by s. 
//
// argument s must point to a struct with pointer type
// fields.   
// argument d must point to a struct with fields that 
// correspond to the fields in s: there must be a field
// in d with the same name as a field in s; the type of
// the field in s must be a pointer to the type of the field
// in d.   
func merge(d, s any) {
    sv := reflect.valueof(s).elem()
    dv := reflect.valueof(d).elem()
    for i := 0; i < sv.numfield(); i++ {
        sf := sv.field(i)
        if sf.isnil() {
            continue
        }
        df := dv.fieldbyname(sv.type().field(i).name)
        df.set(sf.elem())
    }
}
Copier après la connexion

Utilisez une fonction comme celle-ci :

merge(us, input)
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!

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