Smalltalk Pharo 字符串连接而不是流

Smalltalk Pharo String concatenation instead of streams

为什么会出现以下代码:

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

在 Pharo 的方法中发出 String concatenation instead of streams 警告? 单击 [?] 按钮显示:

String concatenation instead of streams
Check for code using string concatenation inside some iteration message.

我正在做一些可以通过流更轻松地完成的事情吗?我想要实现的是创建一个 list 的所有值 a1a9, b1b9c1c9.

它抱怨是因为 t, i asString 部分在收集循环中(您可以在 class RBStringConcatenationRule.[=20= 中查看规则的实际实现]

通常不鼓励使用字符串连接,因为它速度较慢且内存占用较多(关于内存的 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,您可以直接 return 第三行,而不需要 list tempvar。

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

| 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

所以您没有创建临时字符串和间隔。也没有从整数到字符串的转换。