【问题标题】:How to assign value into reflect Field()?如何将值分配给反射字段()?
【发布时间】:2019-09-16 08:48:02
【问题描述】:

我遇到了这样的问题。 如果它们的类型和字段名称相等,我需要比较两个结构。 将值从酸分配到 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)
    }
}

【问题讨论】:

  • 请不要将代码粘贴到 cmets 中,它不可读。您可以更新问题并在那里添加更新的代码,还可以添加您看到的错误。
  • 对不起,这是我在stackoverflow中的第一个问题。
  • 您需要将指针传递给b。例如。 Assing(a, &amp;b).
  • 感谢您的回答。现在我怎样才能将你的答案标记为正确?

标签: go field reflect


【解决方案1】:

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

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

然后你需要稍微修改Assign 的实现,因为指针没有文件。可以使用Elem()方法获取指针指向的struct值。

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)
}

【讨论】:

    猜你喜欢
    • 2012-05-08
    • 2012-07-13
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2012-02-18
    • 1970-01-01
    • 2019-05-04
    相关资源
    最近更新 更多