在Smalltalk中,Array和Literal Array有什么区别?

5
除了大小之外。
例如:
|arr|. arr := Array new: 10

并且。
#(element1,element2, ...)

1
请注意,在数组元素之间没有逗号分隔符。上面的示例将被解析为#(#element1 #'' #element2 #'' ...) - aka.nice
2个回答

5
在这两种形式中,创建的对象类型和元素都是相同的。主要区别在于,在使用 Array with: 时,每次执行代码都会获得一个新的实例;而在使用 #( ) 时,会在方法被接受/编译时创建实例,所以每次执行代码时,数组实例都是相同的。
考虑以下代码:
doSomething
    array := #(6 7 8).
    Transcript show: array.
    array at: 1 put: 3.

第一次执行doSomething时,一切都会正常。第二次,您将看到打印了3、7、8,因为数组与上次调用该方法修改过的相同。

因此,在使用文字时应当小心,主要留给不会被改变的情况。


3
考虑一个具有实例变量阈值的示例类中的此方法:
Example >> #threshold
    ^threshold
Example >> #threshold: anInteger
    threshold := anInteger
Example >> #initialize
    threshold := 0
Example class >> #new
    ^super new initialize

Example >> testArraySum
   | a |
   a := #(4 8 10).
   a sum > threshold ifTrue: [ a at: 1 put: a first - 2 ].
   ^a sum

现在,如果你阅读testArraySum的代码,如果threshold没有改变,那么它应该始终返回相同的结果,不是吗?因为你开始将一个固定值赋给a,然后减去(或不减,这取决于threshold,但我们说它是固定的)一个固定数量,所以它应该是...20。
嗯,如果你评估
Example new testArraySum

多次运行后,你会得到20、18、16等结果...因为数组 #(4 8 10)被修改了。 另一方面,

Example >> testConstantArraySum
   | a |
   a := Array new:  3.
   a at: 1 put: 4; at: 2 put: 8; at: 3 put: 10.
   a sum > threshold ifTrue: [ a at: 1 put: a first - 2 ].
   ^a sum

真正的常数是不变的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接