如何访问未导出的结构字段 [英] How to access unexported struct fields
问题描述
在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屋!