登录
首页 >  Golang >  Go问答

获取未导出的结构体字段的访问方法

来源:stackoverflow

时间:2024-02-08 20:54:23 112浏览 收藏

偷偷努力,悄无声息地变强,然后惊艳所有人!哈哈,小伙伴们又来学习啦~今天我将给大家介绍《获取未导出的结构体字段的访问方法》,这篇文章主要会讲到等等知识点,不知道大家对其都有多少了解,下面我们就一起来看一吧!当然,非常希望大家能多多评论,给出合理的建议,我们一起学习,一起进步!

问题内容

go 1.8 中有没有办法使用 reflect 来访问未导出的字段? 这似乎不再有效:https://stackoverflow.com/a/17982725/555493

请注意,reflect.deepequal 工作得很好(也就是说,它可以访问未导出的字段),但我无法清楚地了解该函数。这是一个显示其实际操作的 go playarea:https://play.golang.org/p/vyevay6evg。源码如下

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 来访问该字段(读取或写入),如下所示:

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.

See full example on the playground.

根据 documentationunsafe.pointer 的这种使用是有效的,并且运行 go vet 不会返回错误。

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

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.

See full example on the playground.

到这里,我们也就讲完了《获取未导出的结构体字段的访问方法》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

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