当字段是指向x的指针时,使用反射设置struct字段的值

时间:2017-09-21 23:17:01

标签: pointers go reflection struct

我已经检查了很多反映问题,我现在已经使用了很多但是我没有找到解决方案。

基本上,我有一个指向各种基元的指针结构。结构是应用程序的配置,字段是指针的原因是我可以在设置为默认的字段和根本没有设置的字段之间确定 - 强制执行“必需”字段。

我会在最后链接源代码,但现在让我们使用一个简单的例子:

type Config struct {
    A *string
    B *int
    C *bool
    D *[]string // wildcard!
}

所以我通过reflect.Value通过reflect.ValueOf(*cfg)抓取每个元素的.Field,我会迭代。

问题是,每个元素都没有通过CanAddrCanSet,我似乎无法找到一种方法来设置指针后面的值。这是语言的限制吗?我需要让我的字段成为非指针吗?那会很糟糕,因为没有办法确定用户是否指定了一个空字符串,或者根本就没有设置它。

设置/附加[]字符串字段的哦和奖励积分!那个混淆了我甚至没有指针混合在一起!

无论如何,相关代码在这里:https://github.com/Southclaws/sampctl/blob/master/settings.go#L95-L116

1 个答案:

答案 0 :(得分:1)

替换这些行:

t := reflect.TypeOf(*cfg)
v := reflect.ValueOf(*cfg)

v := reflect.ValueOf(cfg).Elem()
t := v.Type()

获取可寻址值。

reflect.ValueOf(*cfg)创建的值没有引用可寻址内存。解决方法是取消引用反射域中的指针。

关于[]字符串。因为空切片和空切片之间存在差异,所以可能不需要使用* []字符串。在任何情况下,使用reflect.Append函数追加到切片:

var s []string
v := reflect.ValueOf(&s).Elem()
v.Set(reflect.Append(v, reflect.ValueOf("hello")))
v.Set(reflect.Append(v, reflect.ValueOf("world")))
fmt.Println(s) // prints [hello world]