Maison > Article > développement back-end > Quelle est la bonne façon d'attribuer conditionnellement plusieurs propriétés à une structure
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 ?
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!