使用 Go 的 reflect 包,如果指针为 nil,是否有办法在结构中设置指针?查看 reflect 包,如果 reflect.Value.CanSet()
为 false
,则任何 Set()
调用都会产生 panic 。有没有另一种解决方法,只使用 reflect 包,而不依赖于对结构的任何直接引用?例如,如何在下面的代码中将空姓设置为“Johnson”?
package main
import (
"fmt"
"reflect"
)
type Person struct {
FirstName *string
LastName *string
}
func main() {
p := Person{}
firstName := "Ryan"
p.FirstName = &firstName
rp := reflect.ValueOf(p)
fmt.Println("rp:", rp)
for i := 0; i < rp.NumField(); i++ {
fmt.Printf("%s: Pointer: %d CanSet: %t\n", rp.Type().Field(i).Name, rp.Field(i).Pointer(), rp.Field(i).Elem().CanSet())
}
rp.Field(0).Elem().SetString("Brian")
fmt.Println(*p.FirstName)
// Yields nil pointer error
// rp.Field(1).Elem().SetString("Johnson")
// fmt.Println(*p.LastName)
fmt.Println(rp.Field(1).Type())
fmt.Println(rp.Field(1).CanSet())
// fmt.Println(rp.Field(1).Elem().Type()) // nil pointer here also
fmt.Println(rp.Field(1).Elem().CanSet())
}
最佳答案
您首先需要一个指向 Person{}
的指针,因为您需要为 LastName
字段设置一个值。
p := &Person{}
然后您可以为 LastName
字段设置一个有效的指针值,这将允许您设置字符串值:
rp.Field(1).Set(reflect.New(rp.Field(1).Type().Elem()))
rp.Field(1).Elem().SetString("Jones")
关于pointers - Golang 使用反射在结构中设置 nil 字符串指针值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43744238/