2017-02-10 5 views
5

Кроме того размер.В чем разница между массивом и литеральным массивом в Smalltalk?

Например:

|arr|. arr := Array new: 10 

и

#(element1,element2, ...) 
+0

Обратите внимание, что между элементами массива нет разделителя комы. Пример выше будет проанализирован как # (# element1 # ',' # element2 # ',' ...) –

ответ

5

В обеих формах объект создается собирается быть того же типа и с теми же элементами. Основное различие заключается в том, что при использовании Array with: вы получаете новый экземпляр каждый раз, когда код выполняется, а с #() вы получаете экземпляр, созданный при принятии/компиляции метода, так что каждый раз, когда код выполняется, экземпляр массива тоже самое.

Рассмотрим следующий код:

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

первый раз, когда вы выполнить йоЗотеЬЫпд все будет нормально. Во второй раз вы получите распечатку 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, если порог изменения это не распространяется, он должен всегда retunr то же самое, shouldn' это? Старайтесь, что вы начинаете устанавливать фиксированное значение 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 

действительно постоянны.

Смежные вопросы