Squeak Smalltalk数组中的奇怪行为
我只是被以下行为绊倒了。要复制它,请使用inst var创建一个类:Squeak Smalltalk数组中的奇怪行为,smalltalk,squeak,Smalltalk,Squeak,我只是被以下行为绊倒了。要复制它,请使用inst var创建一个类: Object subclass: #Asdf instanceVariableNames: 'countSeq' classVariableNames: '' poolDictionaries: '' category: 'Asdf' 还有一个懒惰的init getter: countSeq ^countSeq ifNil: [ countSeq:=#(0) asOrderedCollection.
Object subclass: #Asdf
instanceVariableNames: 'countSeq'
classVariableNames: ''
poolDictionaries: ''
category: 'Asdf'
还有一个懒惰的init getter:
countSeq
^countSeq ifNil: [
countSeq:=#(0) asOrderedCollection.
countSeq at: 1 put: (countSeq at: 1)+1.
countSeq
].
这是正确的。当我调用Asdf new countSeq
时,它每次都返回一个OrderedCollection(1)
但是,如果我删除了asOrderedCollection
:
countSeq
^countSeq ifNil: [
countSeq:=#(0).
countSeq at: 1 put: (countSeq at: 1)+1.
countSeq
].
并多次调用Asdf new countSeq
,然后我得到(1)
,(2)
,(3)
。
这怎么解释呢
(在我看来,这个数组的行为就像一个C静态局部变量。事实上,我尝试过:重新编译该方法,不幸的计数器再次从1开始)这是因为文字数组
#(0)
存储在method对象中
此处解释:是的,这确实是语言的陷阱。我在他参考的页面上对托拜厄斯的答案投了赞成票,建议大家彻底阅读。@BerndElkemann这不是语言的陷阱,而是由对象组成的系统的结果。一旦我们的OO思维克服了基于文本的推理,这种行为就会变得自然。一些方言(视觉作品)已经禁止这种行为。修改文字是一件坏事,我们可能在不久的将来禁止在Squeak中这样做(这在Spur VM中是可能的)。@LeandroCaniglia在语言设计中有两个很好的选择:(1)文字应该是不可变的,或者(2)文字应该被认为是“生成对象”(而不是“作为对象”)。(Smalltalk中“文字是对象”的原因是历史性的,不是很好。例如,我永远不会问数组“您使用的是哪种方法?”)在链接的问题中可以看到Tobias和Blablabla999的答案