go - 如何给reflect Field()赋值?

标签 go field reflect

我就遇到过这样的问题。 我需要比较两个结构,如果它们的类型和字段名称相同。 将值从 sour 分配给 dist。我编写了一些代码,但在这里我可以分配 Reflect.Field() 值。你可以帮帮我吗?我在下面创建测试

import (
    "reflect"
    "testing"
)

func Assign(sour interface{}, dist interface{}) uint {
    counter := 0
    source  := reflect.ValueOf(sour)

    target  := reflect.ValueOf(dist)

    typeSource := reflect.TypeOf(sour)


    typeTarget := reflect.TypeOf(dist)
    for i:=0; i<source.NumField(); i++{
        for j:=0; j<target.NumField();j++{
            if (typeSource.Field(i).Type==typeTarget.Field(j).Type && typeSource.Field(i).Name==typeTarget.Field(j).Name){
                counter = counter + 1
                target.FieldByName(typeSource.Field(i).Name).Set(source.Field(i))


            }
        }
    }

    return uint(counter)
}

func TestAssign(t *testing.T) {
    type A struct {
        A string
        B uint
        C string
    }
    type B struct {
        AA string
        B  int
        C  string
    }
    var (
        a = A{
            A: "Тест A",
            B: 55,
            C: "Test C",
        }
        b = B{
            AA: "OKOK",
            B:  10,
            C:  "FAFA",
        }
    )
    result := Assign(a, b)
    switch true {
    case b.B != 10:
        t.Errorf("b.B = %d; need to be 10", b.B)
    case b.C != "Test C":
        t.Errorf("b.C = %v; need to be  'Test C'", b.C)
    case result != 1:
        t.Errorf("Assign(a,b) = %d; need to be 1", result)
    }
}

最佳答案

要使Assign工作,第二个参数必须可寻址,即您需要传递一个指向结构值的指针。

// the second argument MUST be a pointer to the struct
Assing(source, &target)

然后,您需要稍微修改 Assign 的实现,因为指针没有字段。您可以使用 Elem()方法获取指针指向的结构体值。

func Assign(sour interface{}, dist interface{}) uint {
    counter := 0
    source := reflect.ValueOf(sour)

    // dist is expected to be a pointer, so use Elem() to
    // get the type of the value to which the pointer points
    target := reflect.ValueOf(dist).Elem()

    typeSource := reflect.TypeOf(sour)

    typeTarget := target.Type()
    for i := 0; i < source.NumField(); i++ {
        for j := 0; j < target.NumField(); j++ {
            if typeSource.Field(i).Type == typeTarget.Field(j).Type && typeSource.Field(i).Name == typeTarget.Field(j).Name {
                counter = counter + 1
                target.FieldByName(typeSource.Field(i).Name).Set(source.Field(i))

            }
        }
    }

    return uint(counter)
}

关于go - 如何给reflect Field()赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57953306/

相关文章:

html - 表格突出显示和轮廓大小

sql-server - Delphi 6、ADO、MS 数据库 "Date"字段与 ftWideString 相同

angular - 错误 : Can't resolve all parameters for ApplicationModule: (?)

go - 从 slice 中删除元素差异 gccgo 与 gc

go - 单值上下文中的多个值

json - golang - json HTML 转义

jQuery 抓取动态文本区域的值

go - 如何合并两个相同结构类型的 Go 值?

go - 反射(reflect)运行时错误: call of reflect. flag.mustBeAssignable为零值

go - 如何从同一 map 内的另一个函数调用存储在 map 中的函数