2016-11-04 10 views
4

почему бы следующий код:Smalltalk Pharo Объединение строк вместо потоков

| list types | 
list := Heap new. 
types := #('a' 'b' 'c'). 
types do:[ :t | 
    1 to:9 do:[ :i | 
     list add:(t, i asString). 
     ]. 
    ]. 
^ list 

выдайте String concatenation instead of streams предупреждение в методе в Pharo? Нажав кнопку [?] Кнопка показывает:

Объединение строк вместо потоков
Проверьте наличие кода с помощью конкатенации внутри некоторой итерации сообщения.

Я делаю то, что можно сделать проще с потоками? То, что я хочу добиться того, чтобы создать список всех значений a1 в а9, b1 к b9 и c1 к с9.

+1

правила о «schlemiel живописец Algo rithm "https://en.wikipedia.org/wiki/Joel_Spolsky, но здесь явно ложно. –

+0

Я вижу. Как упоминал Джоэл Спольский, «я раньше не сталкивался с этой проблемой, и меня не учили избегать такого рода расточительного использования ресурсов. Я понимаю, что это ложный позитив, но знание о нем помогает гораздо больше всякий раз, когда возникает проблема. –

ответ

8

Он жалуется из-за части t, i asString, который находится внутри цикла сбора (вы можете посмотреть на фактической реализации правила в классе RBStringConcatenationRule.

Обычно конкатенация не рекомендуется, потому что это медленнее и больше памяти интенсивной (IIRC о памяти)

Так что, если вы делаете некоторую тяжелую конкатенацию (подключение много частей в одну строку), поток предпочтительнее:. вы можете посмотреть на большинстве printOn: методов в системе, чтобы увидеть его в действие.

Однако в тривиальных случаях конкатенация с , в порядке, правило предупреждения слишком велико. Предупреждения - это только ... предупреждения, что-то может быть неправ, или что-то может быть написано лучше.

Говоря о лучшей письменной форме, в Smalltalk предпочтительно использовать специализированные методы сбора (select:, collect: ...) за чрезмерно общий do:, например,

| list types | 
types := #('a' 'b' 'c'). 
list := types flatCollect: [ :t | (1 to: 9) collect: [ :i | t , i asString ]. 
^ Heap withAll: list 

(и если вам не нужно Heap вы можете просто вернуть третью строку непосредственно и не имеют list tempvar

+0

Действительно, я не думал о специализированных функциях.Это делает код намного чище! –

1

Чтобы mininize количество создаваемых объектов, вы могли бы сделать так:.

| list types digits | 

list := Heap new. 
types := #($a $b $c). 
digits := (1 to: 9) collect: #asCharacterDigit. 

types do: [ :t | 
    digits do: [ :d | 
     list 
      add: ((String new: 2) 
       at: 1 put: t; 
       at: 2 put: d; 
       yourself) 
      ] ]. 
^ list 

Таким образом, вы не создавая промежуточные строки и интервалы., Ни преобразование из целого числа в строку.