加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

指针 – Golang反射:无法设置包含结构体的界面的字段

发布时间:2020-12-16 19:29:12 所属栏目:大数据 来源:网络整理
导读:我试图实现一个方法来改变可以具有任意结构的对象中的字段的值.当我有一个指向一个结构体的指针时,字段的转换就没有问题.但是当我有一个接口不包含指向结构体的指针但结构本身时,我无法设法更改这些字段:简而言之 // The following doesn't workvar x inter
我试图实现一个方法来改变可以具有任意结构的对象中的字段的值.当我有一个指向一个结构体的指针时,字段的转换就没有问题.但是当我有一个接口不包含指向结构体的指针但结构本身时,我无法设法更改这些字段:简而言之
// The following doesn't work
var x interface{} = A{Str: "Hello"}
// This panics: reflect: call of reflect.Value.Field on ptr Value
reflect.ValueOf(&x).Field(0).SetString("Bye")
// This panics: reflect: call of reflect.Value.Field on interface Value
reflect.ValueOf(&x).Elem().Field(0).SetString("Bye")
// This panics: reflect: reflect.Value.SetString using unaddressable value
reflect.ValueOf(&x).Elem().Elem().Field(0).SetString("Bye")
// This prints `false`. But I want this to be settable
fmt.Println(reflect.ValueOf(&x).Elem().Elem().Field(0).CanSet())

// This works
var z interface{} = &A{Str: "Hello"}
// This prints `true`
fmt.Println(reflect.ValueOf(z).Elem().Field(0).CanSet())

长期:http://play.golang.org/p/OsnCPvOx8F

我已经阅读了The Laws of Reflection,所以我知道,当我有一个指向结构体的指针时,我只能修改字段.所以我的问题现在是:如何获取指向结构数据的指针?

更新:

我使用基本上y:= reflect.New(reflect.TypeOf(x))使它工作,所以y的值现在可以设置.有关广泛的示例,请参阅:https://gist.github.com/hvoecking/10772475

您似乎试图修改存储在接口变量中的动态值.您可以在接口变量上执行的唯一操作是获取或设置动态值(复制操作),并检查存储值的类型.

为了理解为什么这样做,想象有一个这样的操作,我们有以下代码:

var ptr *A = pointer_to_dynamic_value(x)
x = B{...}

ptr现在代表什么?当向接口变量分配新值时,该语言可以自由地重用存储,因此ptr现在可以指向B值的内存,这会破坏语言的类型安全性(目前的编译器存储仅保证为重复使用小价值,但依然存在).

将存储在界面中的值进行变异的唯一安全方式是将值复制出来,然后分配修改后的版本.例如:

a := x.(A)
a.Str = "Bye"
x = a

反射包反映了这些限制,因此表示动态值字段的reflect.Value被认为是只读的.

您可以在第一个示例中设置字段,因为z的动态值是* A指针而不是struct本身:这意味着可以修改引用的结构体.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读