此代码:
((1 to: 10)
inject: (WriteStream on: String new)
into: [ :strm :each |
((each rem: 3) = 0)
ifTrue: [
strm
nextPutAll: each printString;
space;
yourself ]]) contents
失败,因为strm
未定义ifTrue:
块中使用的位置。为什么在那里看不到?
编辑:我在VASt和Pharo中尝试过。
答案 0 :(得分:4)
问题是隐含的ifFalse:
分支返回nil
。要解决此问题,请尝试以下操作:
((1 to: 10)
inject: (WriteStream on: String new)
into: [ :strm :each |
((each rem: 3) = 0)
ifFalse: [strm] "This is needed to avoid nil being returned"
ifTrue: [
strm
nextPutAll: each printString;
space;
yourself ]]) contents
答案 1 :(得分:4)
根据方言(可用的方法),您可以采用更短的方法
((1 to: 10) select: [ :each | (each rem: 3) = 0 ]) joinUsing: ' '
根据经验法则,任何collection do: [ :each | something ifTrue: [] ]
都可以变得更直接,更易读collection select: []
或collection reject: []
这样做会分散几个独立步骤的复杂性(1.过滤,2。添加到流),而不是将它们全部推到一起。
或者如果你想坚持原来的
(((1 to: 10) select: [ :each | (each rem: 3) = 0 ])
inject: (WriteStream on: String new)
into: [ :stream :each |
stream
nextPutAll: each printString;
space;
yourself ]) contents
或
String streamContents: [ :stream |
(1 to: 10)
select: [ :each | (each rem: 3) = 0 ]
thenDo: [ :each |
stream
nextPutAll: each printString;
space
]
]
¹并非总是如此,但在遇到这种情况时总是要记住。