登录
首页 >  Golang >  Go问答

通过反射将字符串分配给结构体

来源:stackoverflow

时间:2024-03-17 14:57:28 177浏览 收藏

在 Go 语言中,使用反射将字符串动态分配给结构体时可能会遇到恐慌。这是因为反射创建的是结构体副本,而不是引用。因此,对副本的更改不会反映在原始结构体中。 要解决此问题,需要使用指针来获取结构体的地址,然后取消引用以获取可寻址的结构体元素。这样,对元素的更改将反映在原始结构体中,避免恐慌。

问题内容

我有一个结构,我希望使用反射动态地将一个字符串更改为另一个字符串。我的问题是新字符串是在堆栈上创建的,因此 set() 方法会出现恐慌。

这对我来说很有意义,但我不知道如何解决它。我不确定将字符串声明为可寻址的简单方法,或者是否可以使用不同的反射技术。

type MyStruct struct {
    SomeField string
}

func main() {
    myStruct := MyStruct{"initial"}
    hello := "hello world"
    
    field := reflect.ValueOf(myStruct).FieldByName("SomeField")
    helloValue := reflect.ValueOf(hello)
    fmt.Printf("hello is on the stack, canAddr is %v\n", helloValue.CanAddr())
    
    // This will panic because canAddr is false
    field.Set(helloValue)
}

https://play.golang.org/p/ghugiqfkxhk


正确答案


go 错误有点用词不当。问题在于结构,而不是字符串。

问题出在这一行: field := Reflect.ValueOf(myStruct).FieldByName("SomeField") 调用 ValueOf 会传入一个副本(在本例中为 myStruct)。由于更改副本不会更改 myStruct,因此会出现恐慌(如果神秘的话,这是有帮助的)。参见【反射第三定律】(https://blog.golang.org/laws-of-reflection#TOC_8

将此行更改为 field :=reflect.ValueOf(&myStruct).Elem().FieldByName("SomeField") 修复了错误(注意 & 获取地址,然后 Elem() 取消引用) p>

当然,我只是在发布问题后才弄清楚这一点,但希望它对其他人有帮助

好了,本文到此结束,带大家了解了《通过反射将字符串分配给结构体》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>