尝试访问私有(包内部)字段让我处于一种奇怪的境地。 我的班级"属性"有一个名为' _forceAccum'的内部字段。 使用此代码试图获取它的值失败:
InstanceMirror bodyMirror = reflect(props);
var value = propsMirror.getField(new Symbol('_forceAccum'));
但如果我改用它:
InstanceMirror bodyMirror = reflect(props);
var value = propsMirror.getField(new Symbol('_forceAccum@434525364'));
它有效。 (我从类镜像中迭代了符号(.toString())得到了" @ ..."。
它应该以这种方式工作吗?它是安全的还是会在下一个版本中改变? (我使用的是1.7.2) 或者只是纯粹的偶然事件?
答案 0 :(得分:3)
您的问题是您拥有库私有名称。它的名称不仅仅是_forceAccum
,它是与_forceAccum
相关的特殊符号,对于库而言是唯一的,但与另一个_forceAccum
不同库。
要使用镜像创建私有符号,您必须使用MirrorSystem.getSymbol作为:MirrorSystem.getSymbol("_forceAccum", libraryMirrorOfLibrary)
。这将为该特定库创建一个库私有符号。您无法创建私有符号,也无需指定其私有的库,或者位于库中(#_forceAccum
将为其出现的库创建正确的符号)。
您使用的另一种选择是查看库并在那里找到已存在的符号:
var forceAccumSymbol =
libraryMirrorOfLibrary.declarations.keys
.where((n) => MirrorSystem.getName(n) == "_forceAccum")
.first;
(如果声明是顶级声明)。
您看到的_forceAccum@something
名称是虚拟机将名称库设为私有的方式。如果使用dart2js进行编译,它将无法正常工作,并且每次运行可能不会有相同的something
,因此您无法将其设置为{0}进入你的代码。
答案 1 :(得分:2)
行为无法保证。
如果您在同一个库中,则可以自己构建符号(使用#_forceAccum
或使用const Symbol("_forceAccum")
或new Symbol("_forceAccum")
)。
从库外部获取符号的最佳方法可能是找到它(使用toString()
进行测试然后缓存它。