如何使用反射更改一段结构的字段?

时间:2017-11-08 19:04:55

标签: go

我有以下https://play.golang.org/p/TlHCX29QZr

if(isset($_COOKIE["beenToCyanCoding"])) {
    echo '
        <style type="text/css">
            #welcomeToCyanCoding {
                display: none;
            }
        </style>';
}
else {
    echo '
        <style type="text/css">
            #welcomeToCyanCoding {
                display: block;
            }
        </style>';
    setcookie("beenToCyanCoding", date("m/d/y"), time() + 10 * 365 * 24 * 60 * 60, "/");
}

如您所见,某些变量是空切片而有些则不是。对于那些空的,我需要添加1个{“fred”,54}结构。对于那些非空的切片,我需要将所有值更改为{“fred”,54}。我事先并不知道这些字段是什么......只是如果有一个字符串字段,那么该值应该是“fred”,如果是一个int字段54。

我能够改变“a”的值,但是其他一切都失败了,因为“恐慌:反映:对slice值的反射调用.Value.NumField”。我不知道该怎么做。谢谢!

1 个答案:

答案 0 :(得分:2)

正如评论中所述,您无法在切片上使用NumField,因为该方法仅适用于reflect.Value种类的reflect.Struct

因此,如果你想要处理这两种类型,你需要知道传入了哪一种。

if rv.Kind() == reflect.Struct {
    changeStruct(rv)
}
if rv.Kind() == reflect.Slice {
    changeSlice(rv)
}

现在,如果要追加到空切片,则必须传入指向切片的指针,否则必须返回新切片。

change(&b)
change(&c)

此外,为了能够初始化您想要追加的单个元素,首先需要知道它的类型,要获得切片元素的类型,首先得到切片的reflect.Type,然后使用它的{{ 1}}获取切片元素类型的方法。使用该类型,您可以使用Elem分配该类型的新值并将其附加到切片。

reflect.New

要循环切片,您可以使用var elem reflect.Value // rv is the slice typ := rv.Type().Elem() if typ.Kind() == reflect.Ptr { elem = reflect.New(typ.Elem()) } if typ.Kind() == reflect.Struct { elem = reflect.New(typ).Elem() } reflect.Value.Len方法。

reflect.Value.Index

代码:

ln := rv.Len()
for i := 0; i < ln; i++ {
    changerv(rv.Index(i))
}

playground