2015-09-27 2 views
3

У меня есть класс в Smalltalk, в котором хранится OrderedCollection объектов. Каждый объект имеет имя. Я хотел бы перебрать объекты OrderedCollection и распечатать имя каждого из этих объектов. Например, в Java я бы что-то вроде:Как распечатать данные объекта из OrderedCollection в Smalltalk

for(int i = 0; i < array.length; ++i) { 
    System.out.println(array[i].getName()); 
} 

Это насколько я в Smalltalk, где «список» является УпорядоченнаяСовокупность:

1 to: list size do: [ 
:x | Transcript show: 'The object name:' list at: x printString; cr. 
] 
+3

'list do: [: объект | Transcript show: 'Имя объекта:', имя объекта; cr] ' –

+0

В Java, чтобы перечислить массив' foo', вы бы более компактно записывали 'for (int i: foo) {...}', который немного более точно отражает правильный способ сделать это в Smalltalk , 'foo do: [: each | ...] '. – lurker

ответ

8

Ваше решение хорошо, за исключением двух маленькие ошибки: (1) вы забыли некоторые скобки и (2) сообщение конкатенации #, отсутствует:

должен был

1 to: list size do: [ 
    :x | Transcript show: 'The object name:' , (list at: x) printString; cr. 
] 

В противном случае объект Transcript получит сообщение #show:at:, которое не понимает. Кроме того, вы должны конкатенировать строку 'The object name: ' с (list at: x) printString, и поэтому вам понадобится сообщение конкатенации #, между ними.

Обратите внимание, что в вашем примере нет необходимости использовать индексы. Вместо того, чтобы итерация от 1 к list size вы могли бы просто перечислить объекты в list коллекции, как это:

list do: [:object | Transcript show: 'The object name: ' , object printString; cr] 

Эта форма, как правило, предпочтительнее, поскольку он позволяет избежать использования промежуточного индекса (x в вашем примере) и силы вы можете получить доступ к элементу коллекции x-, используя #at:, что делает ваш код более удобным для чтения и изменения.

+3

+1, хотя я бы также добавил, что в Smalltalk очень характерно, что переменная итерации должна быть названа 'each' или' eachSomething', если это необходимо, чтобы подчеркнуть ее итеративный характер и что мы делаем что-то для значения _each_ в список. Чтобы быть еще более педантичным, я постараюсь не называть вашу коллекцию 'list', потому что она связывает вас с определенной реализацией коллекции. (Что, если вам нужно позже «Установить»?) Вместо этого я бы рекомендовал, чтобы OP использовал множественное имя, например «учетные записи» или «объекты», или что-то еще в вашем домене. –

+2

Хорошая точка @ AmosM.Carpenter. Общие имена, такие как 'list',' collection' и т. П., Применимы только тогда, когда контекст делает их смысл очевидным (например, ivar 'collection'' PositionableStream' в Pharo.) В противном случае это больше намерений, показывающих использование определенного существительного для элементов, которые содержит ассортимент. По этой же причине я обычно не использую 'each' для общей переменной перечисления и вместо этого говорю' accounts do: [: account | ] '. В любом случае, это всегда полезно, чтобы помочь людям изучать фольклорные конвенции. –

+2

Получите лучшее из обоих миров и используйте 'accounts do: [: eachAccount | ] '. Никогда не бойтесь быть явным, и если кто-то смотрит на строку кода, вложенную в пару уровней, без необходимости смотреть на контекст, они сразу поймут, что 'eachAccount' является переменной итерации, account' может быть переменной экземпляра или temp. Для этой конвенции есть веская причина. :-) –

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