Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 我如何在围棋中获得私人反射值的内容?_Go_Reflection - Fatal编程技术网

Go 我如何在围棋中获得私人反射值的内容?

Go 我如何在围棋中获得私人反射值的内容?,go,reflection,Go,Reflection,我正在尝试为复杂数据类型制作一个通用调试打印机,因为%v倾向于只打印指针值,而不是它们所指向的值。在我必须处理包含reflect.Value字段的结构之前,我一直在处理所有的事情 以下演示代码运行时没有错误: 包干管 进口 fmt 反映 类型MyStruct struct{ i int R.反映价值 } func printContentsvalue接口{}{ //省略:检查值是否实际为结构 rv:=reflect.ValueOfvalue 对于i:=0;i

我正在尝试为复杂数据类型制作一个通用调试打印机,因为%v倾向于只打印指针值,而不是它们所指向的值。在我必须处理包含reflect.Value字段的结构之前,我一直在处理所有的事情

以下演示代码运行时没有错误:

包干管 进口 fmt 反映 类型MyStruct struct{ i int R.反映价值 } func printContentsvalue接口{}{ //省略:检查值是否实际为结构 rv:=reflect.ValueOfvalue 对于i:=0;i
i: 123
R: reflect.Value(456)
但是,如果我将MyStruct的R字段名更改为R,它将失败:

panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
当然,它的失败是正确的,因为这将是一种将未报告的油田带入正确的高尔夫球场的方法,这是一个禁忌


但这让我陷入了一个两难境地:我如何才能访问未报告的reflect.Value所指的内容,而不使用接口,这样我就可以浏览它的内容并进行打印?我查阅了reflect文档,没有发现任何有用的东西…

经过深入研究,我找到了一个解决方案:

获取内部reflect.Value的唯一方法是调用接口并键入assert,但如果在未报告的字段上调用,这将导致死机。解决此问题的唯一方法是使用不安全的包清除只读标志,以便接口方法认为它已导出,而实际上,我们破坏了类型系统:

类型标志uintpttr//reflect/value.go:flag 类型flagROTester结构{ 整数 a int//reflect/value.go:flagStickyRO int//reflect/value.go:flagmbedro //注:flagRO=flagStickyRO | Flagmbedro } var flagOffset uintptr var maskFlagRO标志 变量haseExpectedReflectStruct布尔 函数初始化{ if字段,ok:=reflect.TypeOfreflect.Value{}.FieldByNameflag;ok{ flagOffset=field.Offset }否则{ log.Printlngo-description:exposeInterface被禁用,因为+ reflect.Value结构不再具有标志字段。请打开一个+ 发行于https://github.com/kstenerud/go-describe/issues hasExpectedReflectStruct=false 回来 } rv:=reflect.valueOfFlagProtester{} getFlag:=funcv reflect.Value,名称字符串标志{ 返回flagreflect.ValueOfv.FieldByNamename.FieldByNameflag.Uint } flagRO:=getFlagrv,a | getFlagrv,int^getFlagrv,a maskFlagRO=^flagRO 如果flagRO==0{ log.Printlngo-description:exposeInterface被禁用,因为+ 反射标志类型不再具有Flagmbedro或flagStickyRO位+ 请在https://github.com/kstenerud/go-describe/issues hasExpectedReflectStruct=false 回来 } hasExpectedReflectStruct=true } func canExposeInterface布尔{ return haseExpectedReflectStruct } func exposeInterfacev reflect.Value接口{}{ pFlag:=*flagsunsafe.Pointeruintptrunsafe.Pointer&v+flagsoffset *pFlag&=maskFlagRO 返回v.接口 }
需要注意的是,不安全在所有环境中都是不允许或不可取的,更不用说颠覆类型系统很少是正确的做法。建议您将此类代码设置为以生成标记为条件,并包含一个安全的替代方案。

您是否查看过此类功能的任何现有实现,例如?您可以这样做:请注意,我正在传递指向原始结构的指针,以便字段可寻址。然而,更重要的是,为了实现这一点,您需要使用不安全的软件包,未经适当考虑,不得使用。可能会重复