在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 !! "
答案 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:
也是空的。