将字段/值从 src 复制到 dest 对象

我正在尝试将字段从一个结构值复制到另一个结构值,它们具有相同的字段定义。我有这个程序:


package main


import (


    "log"

    "reflect"

)



func setExistingFields(src interface{}, dst interface{}) {


    fields := reflect.TypeOf(src)

    values := reflect.ValueOf(src)


    num := fields.NumField()

    s := reflect.ValueOf(src).Elem()

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


    for i := 0; i < num; i++ {

        field := fields.Field(i)

        value := values.Field(i)

        fsrc := s.FieldByName(field.Name)

        fdest := d.FieldByName(field.Name)


        if fdest.IsValid() && fsrc.IsValid() {


            if fdest.CanSet() && fsrc.CanSet() {


                fdest.Set(value)


            }

        }


    }

}


// and then we main:

func main() {


    src := struct {

        Foo string

        Bar string

    }{

        "dog",

        "pony",

    }


    dest := struct{ Foo string; Bar string }{}

    setExistingFields(&src, &dest)


    log.Println("dest.Foo", dest.Foo)

}

我运行它,但出现错误:


reflect: 非struct类型的NumField


我不知道那是什么。


这是一个游乐场链接: https ://play.golang.org/p/TsHTfAaeKhc


慕慕森
浏览 101回答 2
2回答

catspeake

试试这个:func setExistingFields(src interface{}, dst interface{}) {&nbsp; &nbsp; srcFields := reflect.TypeOf(src).Elem()&nbsp; &nbsp; srcValues := reflect.ValueOf(src).Elem()&nbsp; &nbsp; dstValues := reflect.ValueOf(dst).Elem()&nbsp; &nbsp; for i := 0; i < srcFields.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; srcField := srcFields.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; srcValue := srcValues.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; dstValue := dstValues.FieldByName(srcField.Name)&nbsp; &nbsp; &nbsp; &nbsp; if dstValue.IsValid() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if dstValue.CanSet() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dstValue.Set(srcValue)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}请注意,您需要额外检查src字段值是否可分配给dst字段类型。编辑:您收到该错误的原因是因为fields此时是指向结构的指针。您需要使用Elem().

汪汪一只猫

这是行不通的:一个结构总是在编译时获得它的“模式”(例如它的字段)......你不能在运行时添加更多字段。我没有看到你的确切用例是什么,但考虑类似map[string]string甚至map[string]interface{}能够“扩展”你传递的东西的内容/字段......
打开App,查看更多内容
随时随地看视频慕课网APP