首頁 > 後端開發 > Golang > 有條件地將多個屬性分配給結構的正確方法是什麼

有條件地將多個屬性分配給結構的正確方法是什麼

WBOY
發布: 2024-02-06 08:05:11
轉載
648 人瀏覽過

有條件地將多個屬性分配給結構的正確方法是什麼

問題內容

我正在為我用 go 寫的 be 的 graphql 查詢開發一個解析器函數。在解析器中,我有想要更新的使用者數據,使用包含多個可能的更新屬性的輸入值。

在 javascript 中,這可以透過解構(偽)快速完成:

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

#目前,我的解析函數如下所示(使用 gqlgen 作為 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
}
登入後複製

這感覺很簡單。在這種情況下迭代結構鍵有意義嗎?或者我還缺少另一種模式嗎?


正確答案


使用函數來減少樣板:

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

...
mergef(&us.firstname, input.firstname)
mergef(&us.lastname, input.lastname)
...
登入後複製

使用反射套件來減少更多樣板:

// 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())
    }
}
登入後複製

使用這樣的函數:

merge(us, input)
登入後複製

以上是有條件地將多個屬性分配給結構的正確方法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板