【问题标题】:What's the difference between the Array and Literal Array in Smalltalk?Smalltalk中的Array和Literal Array有什么区别?
【发布时间】:2017-06-28 21:02:03
【问题描述】:

除了尺寸。

例如:

|arr|. arr := Array new: 10

#(element1,element2, ...)

【问题讨论】:

  • 请注意,数组元素之间没有逗号分隔符。上面的例子会被解析为 #( #element1 #',' #element2 #',' ... )

标签: smalltalk gnu-smalltalk


【解决方案1】:

在这两种形式中,创建的对象将具有相同的类型和相同的元素。主要区别在于,使用Array with: 时,每次执行代码时都会获得一个新实例,而使用#( ) 时,您会获得在方法被接受/编译时创建的实例,因此每次执行代码时都会创建实例数组是一样的。

考虑以下代码:

doSomething
    array := #(6 7 8).
    Transcript show: array.
    array at: 1 put: 3.

第一次执行 doSomething 时一切都会正常。第二次你会得到 3, 7, 8 打印,因为数组和修改的一样 上次调用该方法的时间。

因此,在使用字面量时应该小心,主要是在不会发生变异的情况下使用它们。

【讨论】:

    【解决方案2】:

    在具有实例变量阈值的示例类中考虑此方法:

    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 的代码,如果阈值没有改变,它应该总是返回相同的,不是吗?因为您开始将固定值设置为 a,然后减去(或不减去,取决于阈值,但我们说它是固定的)固定量,所以它应该是...... 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
    

    确实是恒定的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 2018-02-13
      • 1970-01-01
      • 2011-12-01
      相关资源
      最近更新 更多