Smalltalk Pharo字符串连接而不是流

Smalltalk Pharo字符串连接而不是流,smalltalk,pharo,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 在Pharo中的方法中发出字符串串联而不是流警告? 单击[?]按钮显示: 字符串连接而不是流 在某些迭代消息中使用字符串连接检查代码 我是否正在做一些可以通过流更容易

为什么会出现以下代码:

| list types |
list := Heap new.
types := #('a' 'b' 'c').
types do:[ :t |
    1 to:9 do:[ :i |
        list add:(t, i asString).
        ].
    ].
^ list
在Pharo中的方法中发出
字符串串联而不是流
警告? 单击[]按钮显示:

字符串连接而不是流
在某些迭代消息中使用字符串连接检查代码


我是否正在做一些可以通过流更容易地完成的事情?我想要实现的是创建一个所有值的列表a1a9b1b9c1c9

它抱怨的原因是收集循环中的
t部分(您可以在类
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

(如果不需要
可以直接返回第三行,而不需要
列表
临时变量。

来减少创建对象的数量,可以这样做:

| 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

因此,您没有创建中间字符串和间隔,也没有从整数到字符串的转换。

规则是关于“schlemiel The painter algorithm”,但我看到这里明显是一个假阳性。正如Joel Spolsky“提到的”我以前从未遇到过这个问题,也没有人教我如何避免这种浪费资源的行为。我知道这是一种误判,但了解它会在出现问题时帮助更多。事实上,我没有考虑过专门的函数。这使代码更干净!