Smalltalk 没有键或大小为1的值的WeakIdentityKeyDictionary?
在Pharo中尝试此脚本:Smalltalk 没有键或大小为1的值的WeakIdentityKeyDictionary?,smalltalk,pharo,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 := 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 !! "
这似乎是故意的。如果您阅读了WeakKeyDictionary类(
WeakEntityKeyDictionary
的超类)的注释:
我是一本字典,钥匙扣得很紧。这有点危险,因为任何时候我的钥匙都会被拿走。客户端负责通过WeakArray注册我的实例,以便在丢失任何密钥时采取适当的操作由于密钥可能随时消失,我报告的大小可能大于迭代中遇到的密钥数。
(强调矿山)
字典的内部数组仍然具有关联nil-->'hello'
,这就是为什么字典的size
为1,但WeakIdentityKeyDictionary
的关联do:
检查nil
键并避免对其求值(请参见最后一行):
Dictionary#associations
基于associationsDo:
,因此字典关联
也是空的。是有意义的。因此,我想解决(潜在)不一致性的“解决方案”应该是#size
或#isEmpty
的客户首先调用#finalizeevalues
…我不知道您的上下文,但另一种选择是使用另一个类对字典进行子类化或修饰,该类的大小和其他每一条消息都取决于关联。但这可能更难,而且CPU更密集。
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]].