![](/img/trans.png)
[英]How to set a struct member that is a pointer to a string using reflection in Go
[英]How to set a struct member that is a pointer to an arbitrary value using reflection
注意:我想做与如何在 Go 中使用反射设置一个指向字符串的指针的结构成员相同,但以更通用的方式。 现有问题并不能解决我的问题。
我有我想使用反射填充的不同类型字段的结构:
type MyStruct struct {
SomeInt int
SomeString string
SomeIntPtr *int
SomeStringPtr *string
}
我想写入各个字段的值是从配置存储中检索并解析为正确的类型,类似于:
func getValueForField(fieldName string) interface{}
对于int
和*int
类型,该函数返回一个int
(包装在接口中)。 对于string
和*string
,该函数为所有类型返回string
(在接口后面)等等。
- >请注意,它不返回*int
/ *string
!
现在我想将值分配给结构字段:
var field reflect.Value = reflect.ValueOf(ptrToMyStruct).Elem().Field(i)
var value interface{} = getValueForField(....)
var isPointer bool = field.Kind() == reflect.Ptr
// assign "value" to "field":
if isPointer {
// ??
field.Set(reflect.ValueOf(value).Addr()) // panic: reflect.Value.Addr of unaddressable value
} else {
field.Set(reflect.ValueOf(value)) // works
}
将这些值分配给具体类型很容易并且按预期工作。 但是我不能在没有以某种方式获取地址的情况下将int
类型(从getValueForField
返回)分配给*int
字段。 由于我只有一个interface{}
,这需要通过反射来完成。
这是 Go Playground 的链接: https : //play.golang.org/p/zElEGHgx1IO
使用reflect.New()
为字段构造一个新的指针值,从value
设置指向的value
,然后将这个新值设置到指针字段。
例如:
type MyStruct struct {
SomeIntPtr *int
SomeStringPtr *string
}
var ms MyStruct
// Set int pointer
{
var i interface{} = 3 // of type int
f := reflect.ValueOf(&ms).Elem().FieldByName("SomeIntPtr")
x := reflect.New(f.Type().Elem())
x.Elem().Set(reflect.ValueOf(i))
f.Set(x)
}
// Set string pointer
{
var i interface{} = "hi" // of type string
f := reflect.ValueOf(&ms).Elem().FieldByName("SomeStringPtr")
x := reflect.New(f.Type().Elem())
x.Elem().Set(reflect.ValueOf(i))
f.Set(x)
}
fmt.Println("ms.SomeIntPtr", *ms.SomeIntPtr)
fmt.Println("ms.SomeStringPtr", *ms.SomeStringPtr)
这将输出(在Go Playground上尝试):
ms.SomeIntPtr 3
ms.SomeStringPtr hi
所以你的代码可能是这样的:
// assign "value" to "field":
if isPointer {
x := reflect.New(field.Type().Elem())
x.Elem().Set(reflect.ValueOf(value))
field.Set(x)
} else {
field.Set(reflect.ValueOf(value)) // works
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.