英文:
How to set a struct member that is a pointer to a string using reflection in Go
问题
我正在尝试使用反射来设置一个指针。elasticbeanstalk.CreateEnvironmentInput
有一个名为SolutionStackName
的字段,类型为*string
。当我尝试设置任何值时,我得到以下错误:
panic: reflect: call of reflect.Value.SetPointer on ptr Value
以下是我的代码:
...
newEnvCnf := new(elasticbeanstalk.CreateEnvironmentInput)
checkConfig2(newEnvCnf, "SolutionStackName", "teststring")
...
func checkConfig2(cnf interface{}, key string, value string) bool {
log.Infof("key %v, value %s", key, value)
v := reflect.ValueOf(cnf).Elem()
fld := v.FieldByName(key)
if fld.IsValid() {
if fld.IsNil() && fld.CanSet() {
fld.SetPointer(unsafe.Pointer(aws.String(value)))
//aws.String返回一个指针
}
}
...
以下是日志输出:
time="2016-02-20T23:54:52-08:00" level=info msg="key [SolutionStackName], value teststring"
panic: reflect: call of reflect.Value.SetPointer on ptr Value [recovered]
panic: reflect: call of reflect.Value.SetPointer on ptr Value
英文:
I am trying to use reflection to set a pointer. elasticbeanstalk.CreateEnvironmentInput
has a field SolutionStackName
which is of type *string
. I am getting the following error when I try to set any value:
panic: reflect: call of reflect.Value.SetPointer on ptr Value
Here is my code:
...
newEnvCnf := new(elasticbeanstalk.CreateEnvironmentInput)
checkConfig2(newEnvCnf, "SolutionStackName", "teststring")
...
func checkConfig2(cnf interface{}, key string, value string) bool {
log.Infof("key %v, value %s", key, value)
v := reflect.ValueOf(cnf).Elem()
fld := v.FieldByName(key)
if fld.IsValid() {
if fld.IsNil() && fld.CanSet() {
fld.SetPointer(unsafe.Pointer(aws.String(value)))
//aws.String returns a pointer
...
Here is the log output
time="2016-02-20T23:54:52-08:00" level=info msg="key [SolutionStackName], value teststring"
panic: reflect: call of reflect.Value.SetPointer on ptr Value [recovered]
panic: reflect: call of reflect.Value.SetPointer on ptr Value
答案1
得分: 8
Value.SetPointer()
只能在值的类型为 reflect.UnsafePointer
时使用(通过 Value.Kind()
报告),但你的类型是 reflect.Ptr
,所以 SetPointer()
会引发 panic(如文档所述)。
只需使用 Value.Set()
方法来更改结构字段的值(无论它是指针还是非指针都无关紧要)。它期望一个类型为 reflect.Value
的参数,你可以通过调用 reflect.ValueOf()
来获取它,并简单地传递参数 value
的地址:
fld.Set(reflect.ValueOf(&value))
进行测试:
type Config struct {
SolutionStackName *string
}
c := new(Config)
fmt.Println(c.SolutionStackName)
checkConfig2(c, "SolutionStackName", "teststring")
fmt.Println(*c.SolutionStackName)
输出结果(在 Go Playground 上尝试):
<nil>
teststring
英文:
Value.SetPointer()
can only be used if the value's kind is reflect.UnsafePointer
(as reported by Value.Kind()
), but yours is reflect.Ptr
so SetPointer()
will panic (as documented).
Simply use the Value.Set()
method to change the value of the struct field (it being pointer or not, doesn't matter). It expects an argument of type reflect.Value
which you can obtain by calling reflect.ValueOf()
, and simply pass the address of the parameter value
:
fld.Set(reflect.ValueOf(&value))
Testing it:
type Config struct {
SolutionStackName *string
}
c := new(Config)
fmt.Println(c.SolutionStackName)
checkConfig2(c, "SolutionStackName", "teststring")
fmt.Println(*c.SolutionStackName)
Output (try it on the Go Playground):
<nil>
teststring
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论