go - 将一个结构的字段更新为另一个结构

标签 go struct

我有一个结构:

type Person struct {
    FirstName string
    LastName int
    Age int 
    HairColor string
    EyeColor string
    Height string
}

我有一个函数,它接受2个参数,并将第一人称字段更新为第二人称字段:
func updateFields(personA *Person, personB Person) {
    personA.FirstName = personB.FirstName
    personA.LastName = personB.LastName
    // Don't want to change Age.
    personA.HairColor = personB.HairColor
    personA.EyeColor = personB.EyeColor 
    personA.Height = personB.Height

}

除了对值进行硬编码以进行更改之外,我如何遍历这些字段并更新第一个Person使其具有与第二个Person相同的值(“年龄”字段除外)?

最佳答案

为了轻松复制每个字段,您可以简单地执行*personA = personB之类的操作。如果您只需要“不复制”一个特定字段(每次都复制同一个字段),则可以将该字段的值保存在单独的变量中,使用*personA = personB复制所有内容,然后将其复制回。但这仅在非常特殊的情况下有用。例如,这将不允许使用动态字段集进行复制。

如果要更灵活地执行此操作,可以使用反射(下面的示例代码)来执行。

请注意,可能会有一些限制。值得注意的是,您只能设置导出的字段。另外,如果您没有测试这些限制,并且意外地尝试设置了一个不可设置的字段,或者该字段的值不能分配给该字段等,那么reflect包将很乐意为panic。因此,在实际对字段进行.Set(...)之前,添加大量检查是明智的。

import (
    "fmt"
    "reflect"
)

type Person struct {
    FirstName string
    LastName int
    Age int
    HairColor string
    EyeColor string
    Height string
}

func updateFields(personA *Person, personB Person) {
    // .Elem() called to dereference the pointer
    aVal := reflect.ValueOf(personA).Elem()
    aTyp := aVal.Type()

    // no .Elem() called here because it's not a pointer
    bVal := reflect.ValueOf(personB)

    for i := 0; i < aVal.NumField(); i++ {
        // skip the "Age" field:
        if aTyp.Field(i).Name == "Age" {
          continue
        }
        // you might want to add some checks here,
        // eg stuff like .CanSet(), to avoid panics
        aVal.Field(i).Set(bVal.Field(i))
    }
}

func main() {
    b := Person{
        FirstName: "Bruno",
        LastName:  1,
        Age:       2,
        HairColor: "hello",
        EyeColor:  "world",
        Height:    "tall",
    }
    a := Person{}
    fmt.Println(a)
    updateFields(&a, b)
    fmt.Println(a)
}

关于go - 将一个结构的字段更新为另一个结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62220689/

相关文章:

c - 不同数据类型中的指针行为

c - 将数据分配给结构变量会产生编译器错误 : storage size of ‘localAddress’ isn’t known

c - 指针 typedef 结构在 C 中如何工作?

c++ - C++ 'struct name' 中的结构未命名类型

go - 带有环境变量的 Go 中的 exec.Command()

go - 结构上的匿名函数

arrays - 如何生成数字序列

json - 在 Go 中使用嵌套的 [] 结构循环?

go - 二进制字符串转十六进制

go - 无法运行 goinstall