Smalltallk - 如何在类的对象(当前实例)中获取所有实例变量的数组(或集合)?

uno*_*nom 2 smalltalk pharo

假设我们有一个类,我们实例化它,创建该类的实例.该实例有一些我需要使用的由类定义的(实例)变量.我想把所有这些(实例)变量放在一个数组或一些Collection中,这样我就可以迭代它们并将它们设置为某个值,而不是nil.

我怎样才能做到这一点?

Lea*_*lia 5

我想建立@Uko的答案,因为有更直接的方式来实现他的想法.

instSize发送给a 的消息Class将回答其实例的命名实例变量的数量.当然,这将包括在超类中定义的实例变量.

例如,RemoteTempVectorNode instSize答案是17(哇!).因此你可以这样做:

fields := (1 to: anObject class instSize) collect: [:i | anObject instVarAt: i]
Run Code Online (Sandbox Code Playgroud)

然后,改为:

values withIndexDo: [:v :i | anObject instVarAt: i put: v]
Run Code Online (Sandbox Code Playgroud)

values您想要注入对象的新值数组在哪里.

那么,为什么我建议这样做而不是instVarNamed:?因为后者是间接的.如果你看看它的实现,你会看到它必须首先通过发送instVarIndexFor:ifAbsent:到对象的类来找出第i个ivar的名称.换句话说,如果您需要ivar名称,请遵循@ Uko的建议; 否则不要将它们放入等式中,因为它们只会为程序添加CPU周期.

还有一件事.正如@Sean DeNegris在他对你的问题的评论中明智地提出的那样,如果你详细说明为什么你需要这种不寻常的机动,那将是有益的.


编辑:

现在Pharo具有灵活的对象布局,inst var名称和类之间的映射instSize不再有效(在使用新功能的类中).因此,使用仅索引的更简单方法不具有通用性.事实上,在新的"分类法"下instSize,一个对象的(字段数)可能与之不同#numberOfInstanceVariables.我想增加的灵活性有它的成本和好处.