简体   繁体   English

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

[英]Set the value of a struct field with reflection when the field is a pointer-to-x

I've checked quite a lot of reflect questions and I've used it quite a bit now but I've not found a solution for this. 我已经检查了很多反映问题,现在已经使用了很多,但是还没有找到解决方案。

Basically, I have a struct of pointers to various primitives. 基本上,我有一个指向各种原语的指针结构。 The struct is a config for an application and the reason the fields are pointers is so I can determine between a field set to the default and a field that hasn't been set at all - to enforce "required" fields. 该结构是应用程序的配置,并且字段是指针的原因是这样,因此我可以确定设置为默认值的字段与根本没有设置的字段之间的关系-强制执行“必填”字段。

I'll link the source code at the end but lets use a simple example for now: 我将在最后链接源代码,但现在使用一个简单的示例:

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

So I grab the reflect.Value via reflect.ValueOf(*cfg) which gives me a .Field on each element, which I iterate through. 所以,我抢reflect.Value通过reflect.ValueOf(*cfg)给了我一个.Field每一个元素,我遍历。

The thing is, each element doesn't pass CanAddr or CanSet , I can't seem to find a way to set the value held behind the pointer. 问题是,每个元素都没有传递CanAddrCanSet ,我似乎找不到找到设置指针后面的值的方法。 Is this a limitation of the language? 这是语言的限制吗? Will I need to make my fields non-pointers? 我是否需要使字段变为非指针? That would suck as there would be no way to determine if a user specified an empty string or just didn't set it at all for example. 那样会很糟糕,因为无法确定用户是指定了空字符串还是根本没有设置空字符串。

Oh and bonus points for setting/appending a []string field! 哦,还有用于设置/附加[] string字段的奖励积分! That one confused me even without pointers thrown in the mix! 即使没有指针混在一起,那个人也使我感到困惑!

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

Replace these lines: 替换这些行:

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

with

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

to get an addressable value. 获得可寻址的值。

The value created by reflect.ValueOf(*cfg) has no reference to addressable memory. reflect.ValueOf(*cfg)创建的值没有引用可寻址内存。 The fix is to dereference the pointer in the reflect domain. 解决方法是在反射域中取消对指针的引用。

Regarding the []string. 关于[]字符串。 Because there's a difference between a null slice and an empty slice, there may be no need to use *[]string. 由于空片和空片之间存在差异,因此可能不需要使用* []字符串。 In any case, use the reflect.Append function to append to a slice: 无论如何,都可以使用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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM