如何在Golang中访问未导出的struct字段? [英] How to access unexported struct fields in Golang?

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

问题描述

是否可以使用Reflect访问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的使用是有效的>不返回错误.

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.

在操场上查看完整示例.

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

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