【问题标题】:Modifying struct value using reflection and loop使用反射和循环修改结构值
【发布时间】:2021-07-19 10:51:52
【问题描述】:

我想遍历一个结构并使用反射修改字段值。如何设置?

func main() {
    x := struct {
        Foo string
        Bar int
    }{"foo", 2}
    StructCheck(Checker, x)
}

func Checker(s interface{}) interface{} {
    log.Println(s)
    return s
}

func StructCheck(check func(interface{}) interface{}, x interface{}) interface{} {
    v := reflect.ValueOf(x)
    for i := 0; i < v.NumField(); i++ {
        r := check(v.Field(i))
        w := reflect.ValueOf(&r).Elem()

        log.Println(w.Type(), w.CanSet())

        // v.Field(i).Set(reflect.ValueOf(w))

    }
    return v
}

运行 Set() 会导致恐慌并显示:reflect.Value.Set using unaddressable value

【问题讨论】:

    标签: go reflection


    【解决方案1】:

    您必须将可寻址的值传递给函数。

    StructCheck(Checker, &x)
    

    取消引用 StructCheck 中的值:

    v := reflect.ValueOf(x).Elem() // Elem() gets value of ptr
    

    还有一些其他问题。这是更新的代码:

    func StructCheck(check func(interface{}) interface{}, x interface{}) {
        v := reflect.ValueOf(x).Elem()
        for i := 0; i < v.NumField(); i++ {
            r := check(v.Field(i).Interface())
            v.Field(i).Set(reflect.ValueOf(r))
    
        }
    }
    

    Run it on the Playground.

    【讨论】:

    • 但是当我尝试将它转换为 x 的结构时,它再次出现恐慌,有什么办法可以解决这个问题? link
    • @ned 我编辑了答案以从 StructCheck 中删除返回值。因为调用者已经有了值,所以不需要再从返回值中获取值。
    猜你喜欢
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    相关资源
    最近更新 更多