如何在Go中使用反射设置作为指向字符串的指针的结构成员

des*_*Joe 6 string reflection struct pointers go

我正在尝试使用反射来设置指针。elasticbeanstalk.CreateEnvironmentInput有一个SolutionStackName类型为 的字段*string。当我尝试设置任何值时出现以下错误:

panic: reflect: call of reflect.Value.SetPointer on ptr Value
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

    ...
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

...
Run Code Online (Sandbox Code Playgroud)

这是日志输出

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
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 7

Value.SetPointer()只能用来当值的是那种reflect.UnsafePointer(通过报道Value.Kind()),但你是reflect.Ptr如此SetPointer()就会死机(如记录)。

只需使用该Value.Set()方法更改 struct 字段的值(是否为指针,无关紧要)。它需要一个reflect.Value您可以通过调用获得的类型的参数reflect.ValueOf(),并简单地传递参数的地址value

fld.Set(reflect.ValueOf(&value))
Run Code Online (Sandbox Code Playgroud)

测试它:

type Config struct {
    SolutionStackName *string
}

c := new(Config)
fmt.Println(c.SolutionStackName)
checkConfig2(c, "SolutionStackName", "teststring")
fmt.Println(*c.SolutionStackName)
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上试试):

<nil>
teststring
Run Code Online (Sandbox Code Playgroud)