Heim > Backend-Entwicklung > Golang > Was ist der richtige Weg, um einer Struktur mehrere Eigenschaften bedingt zuzuweisen?

Was ist der richtige Weg, um einer Struktur mehrere Eigenschaften bedingt zuzuweisen?

WBOY
Freigeben: 2024-02-06 08:05:11
nach vorne
667 Leute haben es durchsucht

Was ist der richtige Weg, um einer Struktur mehrere Eigenschaften bedingt zuzuweisen?

Frageninhalt

Ich entwickle eine Parserfunktion für die GraphQL-Abfrage von be, die ich in go geschrieben habe. Im Parser habe ich Benutzerdaten, die ich mithilfe eines Eingabewerts aktualisieren möchte, der mehrere mögliche Aktualisierungseigenschaften enthält.

In Javascript geht das schnell mit Destrukturierung (Pseudo):

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

Derzeit sieht meine Parser-Funktion so aus (mit gqlgen als Graphql-Go-Parser):

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
}
Nach dem Login kopieren

Das fühlt sich so einfach an. Ist es in diesem Fall sinnvoll, die Strukturschlüssel zu durchlaufen? Oder gibt es ein anderes Muster, das mir fehlt?


Richtige Antwort


Verwenden Sie Funktionen, um die Boilerplate zu reduzieren:

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

...
mergef(&us.firstname, input.firstname)
mergef(&us.lastname, input.lastname)
...
Nach dem Login kopieren

Nutzen Sie das Reflexionspaket, um weitere Boilerplate zu reduzieren:

// 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())
    }
}
Nach dem Login kopieren

Verwenden Sie eine Funktion wie diese:

merge(us, input)
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWas ist der richtige Weg, um einer Struktur mehrere Eigenschaften bedingt zuzuweisen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage