gpt4 book ai didi

go - 有选择地复制 go struct 字段

转载 作者:IT王子 更新时间:2023-10-29 01:56:50 25 4
gpt4 key购买 nike

我想要一种方法来有选择地将 Go 字段从一个结构复制到另一个结构。这使我可以更新 数据从一个结构到另一个结构,而无需更改某些信息。这是我想出的解决方案。这取决于设置“更新”的标签字段。非常感谢任何反馈,使它更强大或更好,或者为什么这只是一个坏主意。

import (
"errors"
"fmt"
"reflect"
)

func UpdateStruct(src, dst interface{}) error {
if reflect.TypeOf(src) != reflect.TypeOf(dst) {
return errors.New("structs not of same type")
}

if reflect.ValueOf(src).Kind() != reflect.Ptr {
return errors.New("arguments must be pointers")
}

srcVal := reflect.ValueOf(src).Elem()
srcType := srcVal.Type()

dstVal := reflect.ValueOf(dst).Elem()

for i := 0; i < srcVal.NumField(); i++ {
s := srcType.Field(i)
if tag := s.Tag.Get("update"); tag == "" {
continue
}
fieldName := srcType.Field(i).Name
d := dstVal.FieldByName(fieldName)
if d.IsValid() {
if d.CanSet() {
d.Set(srcVal.Field(i))
} else {
return fmt.Errorf("cannot set field: %s", fieldName)
}
} else {
return fmt.Errorf("invalid field: %s", fieldName)
}

}
return nil
}

示例结构:

type Tester struct {
ID string
Name string `update:"true"`
Date time.Time `update:"true"`
Decimal float64 `update:"true"`
Number int `update:"true"`
CaseID uuid.UUID `update:"true"`
}

最佳答案

如果参数不是指向结构的指针,代码将崩溃。检查指针,但不检查指向结构的指针。添加此代码:

srcVal := reflect.ValueOf(src).Elem()
if srcVal.Kind() != reflect.Struct {
return errors.New("arguments must be pointers to structs")
}

因为该函数以指向结构的指针开始,所以可以保证字段是可设置的。因为字段值是从有效的结构值中获得的,所以字段保证是有效的。除了名称之外,还可以通过索引访问字段。鉴于此,内部循环可以简化为:

for i := 0; i < srcVal.NumField(); i++ {
s := srcType.Field(i)
if tag := s.Tag.Get("update"); tag == "" {
continue
}
dstVal.Field(i).Set(srcVal.Field(i))
}

Run it on the playground

关于go - 有选择地复制 go struct 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52287035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com