Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 使用反射设置nil*int32结构字段_Go_Reflection - Fatal编程技术网

Go 使用反射设置nil*int32结构字段

Go 使用反射设置nil*int32结构字段,go,reflection,Go,Reflection,我试图通过反射设置anil*int的值 在下面的示例中,replaceNilWithNegativeOne应将任何nil*int32字段(标记为grib:“foo”)替换为指向-1的指针 但是,当代码运行时,reflect会因使用不可寻址的值设置而陷入恐慌状态panic:reflect:reflect.Value.Set 我在其他几个地方看到了我在这里提出的几乎完全相同的问题,例如: 以及非SO研究 我知道答案一定在那些回答中的某个地方,但我仍然无法将这些点连接起来。除了在下面的示例

我试图通过反射设置a
nil
*int
的值

在下面的示例中,
replaceNilWithNegativeOne
应将任何
nil
*int32
字段(标记为
grib:“foo”
)替换为指向-1的指针

但是,当代码运行时,reflect会因使用不可寻址的值设置而陷入恐慌状态
panic:reflect:reflect.Value.Set

我在其他几个地方看到了我在这里提出的几乎完全相同的问题,例如:

  • 以及非SO研究
我知道答案一定在那些回答中的某个地方,但我仍然无法将这些点连接起来。除了在下面的示例中看到的实现之外,我还尝试了几种实现,但它们似乎都会导致segfault,或者更常见的是,导致不可修复的值恐慌

我很清楚,
fieldPtr.CanSet()==false
,但是,既然如此,我该如何实现我想要实现的目标呢

示例

// https://play.golang.org/p/yZOtYxwTzUs
package main

import (
    "log"
    "reflect"
    "strings"
)

func main() {
    type testStruct struct {
        SomeField *int32 `grib:"foo"`
    }
    testStructInstance := testStruct{
        SomeField: nil,
    }
    replaceNilWithNegativeOne(testStructInstance)

    if *testStructInstance.SomeField != int32(-1) {
        // We never get here
        log.Println("Didn't get set")
    }
}

func replaceNilWithNegativeOne(obj interface{}) (err error) {
    objType := reflect.TypeOf(obj)
    for i := 0; i < objType.NumField(); i++ {
        if t, ok := objType.Field(i).Tag.Lookup("grib"); ok {
            if strings.Contains(t, "foo") {
                fieldPtr := reflect.ValueOf(obj).Field(i)
                if fieldPtr.Kind() != reflect.Ptr {
                    // do some stuff
                    break
                }
                if fieldPtr.IsNil() {
                    v := -1
                    // I know this isn't working because the CanSet() == false
                    // But I want to set the value to -1.
                    fieldPtr.Set(reflect.ValueOf(&v))
                    continue
                }
            }
        }
    }
    return
}
//https://play.golang.org/p/yZOtYxwTzUs
包干管
进口(
“日志”
“反映”
“字符串”
)
func main(){
类型testStruct struct{
SomeField*int32`grib:“foo”`
}
testStructInstance:=testStruct{
SomeField:零,
}
replaceNilWithNegativeOne(testStructInstance)
如果*testStructInstance.SomeField!=int32(-1){
//我们永远都到不了这里
log.Println(“未设置”)
}
}
func replaceNilWithNegativeOne(obj接口{})(错误){
objType:=reflect.TypeOf(obj)
对于i:=0;i
这里有两个问题。第一个是需要一个值。将指向结构的指针传递给函数,而不是结构值:

replaceNilWithNegativeOne(&testStructInstance)
在函数中,调用以获取结构的反射值

另一个问题是代码将int赋值给int32。使用int32(-1)修复此问题

以下是更新后的函数,其中包含以下更改:

replaceNilWithNegativeOne(obj interface{}) (err error) {
    v := reflect.ValueOf(obj).Elem()
    t := v.Type()
    for i := 0; i < t.NumField(); i++ {
        if grib, ok := t.Field(i).Tag.Lookup("grib"); ok {
            if strings.Contains(grib, "foo") {
                fv := v.Field(i)
                if fv.Kind() != reflect.Ptr {
                    // do some stuff
                    break
                }
                if fv.IsNil() {
                    iv := int32(-1)
                    fv.Set(reflect.ValueOf(&iv))
                    continue
                }
            }
        }
    }
    return nil
}
replaceNilWithNegativeOne(obj接口{})(错误){
v:=reflect.ValueOf(obj).Elem()
t:=v.Type()
对于i:=0;i