簡體   English   中英

GNU Smalltalk - 從whileTrue循環中斷而不返回

[英]GNU Smalltalk - Break from whileTrue loop without return

什么是簡單而簡潔的方法來打破GNU Smalltalk中不需要返回的whileTrue循環?

這是我的代碼。 如果char_stack為空,我想在結束時從第31行的循環中斷。

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

任何幫助將非常感激。

一般來說,除了從封閉方法返回之外,Smalltalk沒有辦法從循環中斷開。

嘗試將循環提取到另一個方法中,您可以從該方法返回到循環中斷。

在某種程度上,Smalltalk語言甚至沒有循環...但是有些方法碰巧不止一次地評估塊。 因此,它沒有一種特殊的方法來終止“循環”。 回歸就是這樣。

如果您還沒有這樣做,請熟悉Collection的不同迭代方法: do: , select:collect: , detect:ifNone: ,...后者是另一種在集合上運行“不完整”循環的方法,但它並沒有解決你希望“休息”的所有情況。

Byte雜志(1982)的一篇題為Peter Deutsch 的Smalltalk-80系統中的建築控制結構的文章,展示了為循環內部可能發生的偶發事件實現while循環中斷是多么容易。

為了實現這一點,我們只需要一個新的類和BlockClosure的擴展,總共有9行代碼 (!)。

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 ,因此當從loop exit計算[^nil]時,流退出value並在loop value之后立即轉到其發送方。

Deutsch發現的突出推論是, 可以使用這種在ivar中定義出口塊的相同技巧來構建 Exceptions 的整個機制,例如: exit := [^nil]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM