【发布时间】:2018-09-20 17:15:05
【问题描述】:
我正在尝试通过反射设置nil *int 的值。
在下面的示例中,replaceNilWithNegativeOne 应将任何 nil *int32 字段(标记为 grib:"foo")替换为指向 -1 的指针。
但是,当代码运行时,reflect 会出现 panic: reflect: reflect.Value.Set using unaddressable value 恐慌。
我几乎在其他几个地方看到了我在这里提出的问题,例如:
- Using reflect, how do you set the value of a struct field?
- Using reflect, how do you initialize value of a struct pointer field?
- reflect.Value.Set using unaddressable value
- Set a pointer to a field using reflection
- 以及非 SO 研究。
我知道答案一定在某个地方的那些响应中,但我仍然无法连接这些点。除了您在下面的示例中看到的实现之外,我还尝试了几种实现,但它们似乎都导致了段错误,或者更常见的是导致无法处理的值恐慌。
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
}
【问题讨论】:
标签: go reflection