WeakIdentityKeyDictionary没有大小为1的键或值?

时间:2015-10-20 02:14:59

标签: smalltalk pharo

在Pharo中尝试此脚本:

dictionary := WeakIdentityKeyDictionary new.
key := Object new.
dictionary at: key put: 'hello'.
dictionary size. " --> 1 "
key := nil.
2 timesRepeat: [Smalltalk garbageCollect].

到现在为止,字典应该是空的。但是:

dictionary keys isEmpty. " --> true"
dictionary values isEmpty. " --> true "

正如所料,但

dictionary isEmpty. " --> false ??"
dictionary size. " --> 1 !! "

1 个答案:

答案 0 :(得分:4)

这似乎是设计的。如果您阅读WeakKeyDictionary类(WeakIdentityKeyDictionary的超类)的注释:

  

我是一本只拿着我的钥匙的字典。这有点危险,因为任何时候我的钥匙都可以消失。客户负责通过WeakArray注册我的实例,以便在丢失任何密钥时可以采取适当的措施。 由于密钥可能随时消失,我报告的大小可能会大于迭代中遇到的密钥数。

(强调我的)

字典的内部数组仍然具有关联nil --> 'hello',这就是字典的size为1,但WeakIdentityKeyDictionary的{​​{1}}检查associationsDo:的原因键和避免评估它们(见最后一行):

nil

associationsDo: aBlock "Evaluate aBlock for each of the receiver's elements (key/value associations)." super associationsDo: [:association | | key | "Hold onto the key so it won't be collected while the block is evaluated." key := association key. key ifNotNil:[aBlock value: association]]. 基于Dictionary#associations,因此associationsDo:也是空的。