3 回答
TA贡献1798条经验 获得超3个赞
未导出的字段仅用于声明包。别再惹他们了。他们不适合你。
链接的答案只能通过使用 package 来访问它unsafe
,这不适合日常使用。包装unsafe
中应附有“请勿触摸”手册。
如果您确实需要访问unexportedResource
,请将其导出。要么是字段,要么向调用 的类型添加一个方法unexportedResource.Close()
。或者向包中添加执行此操作的实用程序函数(同一包中的函数可以访问未导出的字段和标识符)。
TA贡献1789条经验 获得超10个赞
但这里有一种使用reflectand来做到这一点的方法unsafe:
var t pkg.T
v := reflect.ValueOf(&t).Elem()
f := v.FieldByName("t")
rf := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem()
rf.MethodByName("Print").Call(nil)
游乐场:https://play.golang.org/p/CmG9e4Bl9gg
TA贡献1860条经验 获得超9个赞
恐怕你想要做的事情通过反思是不可能的。
下面是reflect.Call的实现:
func (v Value) Call(in []Value) []Value {
v.mustBe(Func)
v.mustBeExported()
return v.call("Call", in)
}
正如您所看到的,有一个显式检查(即mustBeExported())是否Value从导出字段获取。
通常,字段不导出是有原因的。如果您想操作该字段,则必须使用该ExportedStruct结构实现的方法。
如果您可以修改定义的代码ExportedStruct,则可以轻松地Close在其上实现包装方法。例如:
type ExportedStruct struct{
unexportedResource ExportedType
}
func (e ExportedStruct) Close(){
e.unexportedResource.Close()
}
- 3 回答
- 0 关注
- 132 浏览
添加回答
举报