GNU Smalltalk-从whileTrue循环中中断而不返回

时间:2018-10-06 22:15:54

标签: loops while-loop break smalltalk gnu-smalltalk

在GNU Smalltalk中不需要返回的简单whileTrue循环中断方法是什么?

这是我的代码。如果char_stack为空,我想从第31行的结尾处中断。

https://gist.github.com/SYZYGY-DEV333/ea3f5eeb3473927c8faa294bb72a8858

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

通常,Smalltalk除了从封闭方法返回之外,没有其他方法可以使循环中断。

尝试将循环提取到另一个方法中,您可以从该方法返回以中断循环。

从某种意义上说,Smalltalk语言甚至没有循环...但是某些方法碰巧对块进行了多次评估。因此,它没有终止“循环”的特殊方法。回报就是方法。

如果您尚未这样做,请熟悉Collection的不同迭代方法:do:select:collect:detect:ifNone:,...是对集合运行“不完整”循环的另一种方法,但是并不能解决您可能希望“中断”的所有情况。

答案 1 :(得分:3)

Peter Deutsch 的Byte杂志(1982年)中的一篇题为《 在Smalltalk-80系统中构建控制结构》 的文章显示了在实现以下目标的同时,实现以下任务的容易程度:可能在循环内发生的偶发事件的循环中断。

要实现此目的,我们只需要一个新类和一个BlockClosure扩展名,就可以构成总共总共 9行代码<​​/ strong>(!)。

BlockWithExitObject的子类,具有两个ivars exitblock以及以下方法

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