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

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

WBOY
WBOY轉載
2024-02-06 08:05:11592瀏覽

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

問題內容

我正在為我用 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刪除