在GNU Smalltalk中不需要返回的简单whileTrue
循环中断方法是什么?
这是我的代码。如果char_stack
为空,我想从第31行的结尾处中断。
https://gist.github.com/SYZYGY-DEV333/ea3f5eeb3473927c8faa294bb72a8858
任何帮助将不胜感激。
答案 0 :(得分:4)
通常,Smalltalk除了从封闭方法返回之外,没有其他方法可以使循环中断。
尝试将循环提取到另一个方法中,您可以从该方法返回以中断循环。
从某种意义上说,Smalltalk语言甚至没有循环...但是某些方法碰巧对块进行了多次评估。因此,它没有终止“循环”的特殊方法。回报就是方法。
如果您尚未这样做,请熟悉Collection的不同迭代方法:do:
,select:
,collect:
,detect:ifNone:
,...是对集合运行“不完整”循环的另一种方法,但是并不能解决您可能希望“中断”的所有情况。
答案 1 :(得分:3)
Peter Deutsch 的Byte杂志(1982年)中的一篇题为《 在Smalltalk-80系统中构建控制结构》 的文章显示了在实现以下目标的同时,实现以下任务的容易程度:可能在循环内发生的偶发事件的循环中断。
要实现此目的,我们只需要一个新类和一个BlockClosure
扩展名,就可以构成总共总共 9行代码</ strong>(!)。
类:BlockWithExit
,Object
的子类,具有两个ivars exit
和block
以及以下方法
on: aBlock
block := aBlock
value
exit := [^nil].
^block value
exit
exit value
扩展
BlockClosure>>withExit
^BlockWithExit new on: self
就是这样!
示例
找到一个集合的最大值,直到其耗尽或找到nil
(偶发事件)
maxBeforeNil: aCollection
| max supplier loop |
max := 0.
supplier := aCollection readStream.
loop := [
[supplier atEnd]
whileFalse: [
value := supplier next.
value isNil ifTrue: [loop exit].
max := max max: value]] withExit.
loop value.
^max
为什么这样做会起作用?因为具有非本地返回的块会从定义该块的方法中退出。
在这种情况下,此方法为BlockWithExit>>value
,因此,当从[^nil]
对loop exit
进行求值时,流将退出value
并在{{1之后}}。
Deutsch发现的杰出推论是整个机制 loop value
可以使用在ivar中定义退出块的相同技巧来构建像:Exceptions
。