[英]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行代碼 (!)。
類 : 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
,因此當從loop exit
計算[^nil]
時,流退出value
並在loop value
之后立即轉到其發送方。
Deutsch發現的突出推論是, 可以使用這種在ivar中定義出口塊的相同技巧來構建 Exceptions
的整個機制,例如: exit := [^nil]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.