英文:
Golang set nil string pointer value in struct using reflect
问题
使用Go的reflect包,是否有办法在结构体中设置一个指针,即使该指针为nil?查看reflect包,如果reflect.Value.CanSet()
为false
,那么任何Set()
调用都会导致恐慌。是否有另一种方法来解决这个问题,只使用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())
}
在Golang Playground中查看:链接
英文:
Using Go's reflect package, is there a way to set a pointer in a struct if the pointer is nil? Looking at the reflect package, if reflect.Value.CanSet()
is false
then any Set()
calls will yield a panic. Is there another way around this, only using the reflect package, not depending on any direct reference to the struct? For example, how can I set the empty last name as "Johnson" in the code below?
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())
}
答案1
得分: 11
你首先需要一个指向 Person{}
的指针,因为你需要给 LastName
字段设置一个值。
p := &Person{}
然后,你可以将一个有效的指针值设置给 LastName
字段,这将允许你设置字符串值:
rp.Field(1).Set(reflect.New(rp.Field(1).Type().Elem()))
rp.Field(1).Elem().SetString("Jones")
https://play.golang.org/p/f5MjpkDI2H
英文:
You first need a pointer to a Person{}
, because you need to set a value to the LastName
Field.
p := &Person{}
Then you can set a valid pointer value to the LastName
field, which will allow you to set the string value:
rp.Field(1).Set(reflect.New(rp.Field(1).Type().Elem()))
rp.Field(1).Elem().SetString("Jones")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论