如何访问未导出的结构字段 [英] How to access unexported struct fields

查看:99
本文介绍了如何访问未导出的结构字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Go 1.8中是否可以使用反射来访问未导出的字段?这似乎不再起作用: https://stackoverflow.com/a/17982725/555493

Is there a way to use reflect to access unexported fields in Go 1.8? This no longer seems to work: https://stackoverflow.com/a/17982725/555493

请注意, reflect.DeepEqual 可以很好地工作(也就是说,它可以访问未导出的字段),但是我无法对该函数做任何正面或反面的事情.这是一个可以显示实际运行情况的围棋游戏区域: https://play.golang.org/p/vyEvay6eVG .src代码在下面

Note that reflect.DeepEqual works just fine (that is, it can access unexported fields) but I can't make heads or tails of that function. Here's a go playarea that shows it in action: https://play.golang.org/p/vyEvay6eVG. The src code is below

import (
"fmt"
"reflect"
)

type Foo struct {
  private string
}

func main() {
    x := Foo{"hello"}
    y := Foo{"goodbye"}
    z := Foo{"hello"}

    fmt.Println(reflect.DeepEqual(x,y)) //false
    fmt.Println(reflect.DeepEqual(x,z)) //true
}

推荐答案

如果该结构是可寻址的,则可以使用 unsafe.Pointer 来访问该字段(读取或写入),就像这样:

If the struct is addressable, you can use unsafe.Pointer to access the field (read or write) it, like this:

rs := reflect.ValueOf(&MyStruct).Elem()
rf := rs.Field(n)
// rf can't be read or set.
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
// Now rf can be read and set.

在操场上查看完整示例.

根据文档,这种对 unsafe.Pointer 的使用是有效的并运行 go vet 不会返回任何错误.

This use of unsafe.Pointer is valid according to the documentation and running go vet returns no errors.

如果该结构不可寻址,此技巧将不起作用,但是您可以创建一个可寻址的副本,如下所示:

If the struct is not addressable this trick won't work, but you can create an addressable copy like this:

rs = reflect.ValueOf(MyStruct)
rs2 := reflect.New(rs.Type()).Elem()
rs2.Set(rs)
rf = rs2.Field(0)
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
// Now rf can be read.  Setting will succeed but only affects the temporary copy.

在操场上查看完整示例.

这篇关于如何访问未导出的结构字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆