Maison  >  Article  >  développement back-end  >  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
WBOYavant
2024-02-06 08:05:11592parcourir

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
}

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)
...

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())
    }
}

Utilisez une fonction comme celle-ci :

merge(us, input)

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer