smalltalk块-我可以显式设置返回值并停止执行该块吗? [英] smalltalk block - can I explicitly set the returning value and stop executing the block?

查看:88
本文介绍了smalltalk块-我可以显式设置返回值并停止执行该块吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#value:消息的返回值,当发送到一个块时,是该块中最后一个句子的值.因此[ 1 + 2. 3 + 4. ] value的值为7. 我发现有时候很难使用.有没有一种方法可以显式设置返回值并停止执行该块?

The return value of #value: message, when sent to a block, is the value of the last sentence in that block. So [ 1 + 2. 3 + 4. ] value evaluates to 7. I find that hard to use sometimes. Is there a way to explicitly set the returning value and stop executing the block?

为了运动,请尝试在不使用我想象中的#return:消息的情况下重写此块,并查看它变得多么丑陋.我一定想念一些东西.

For exercise, try rewriting this block without using my imaginary #return: message and see how ugly it gets. I must be missing something.

[ :one :two |
  one isNil ifTrue: [ two isNil ifTrue: [ self return: nil ] ifFalse: [ self return: true ] ].
  two ifNil: [ self return: false ].

 (one > two)
  ifTrue: [ self return: true ]
  ifFalse: [ (one < two)
              ifTrue: [ self return: false ]
              ifFalse: [ self return: nil ]
            ].
]

self return: sth确实是废话,但是在某些级别上确实有意义:)

self return: sth really is nonsense, but it does make sense at some level :)

推荐答案

在块内没有什么类似于保护子句-blah ifTrue: [^ foo]-因为^是非本地返回,是从调用该块的方法返回的而不是块本身.

There's nothing like a guard clause - blah ifTrue: [^ foo] - inside a block, because ^ is a non-local return, returning from the method calling the block rather than the block itself.

大块-像任何大块一样-应该重构为更小,更易于理解/易于处理的子部分,但有时并非总是如此.我的意思是说,这个答案是建议您尝试不能以通常的方式真正简化的选项.

Big blocks - like big anythings - should be refactored into smaller, more understandable/tractable subparts, but sometimes that's not always possible. I mean this answer to suggest options to try when you can't really simplify in the usual ways.

如果您的代码块确实是如此复杂,并且您无法使其变得更简单(例如,将其拆分过多会使信息离域,则可以使用显式的返回值).特别是,如果您的代码块未返回nil,则可以执行类似的操作

If your block is really that complicated, and you can't get it simpler (splitting it up delocalises the information too much, for instance) then perhaps you can use an explicit return value. In particular, if your block doesn't return nil you could do something like

[:one :two | | result |
    result := (one isNil and: [two isNil]) ifTrue: [false].
    result ifNil: ["do one thing, possibly setting result"].
    result]

如果您的代码块可以返回nil,则需要另一个哨兵值:

If your block can return nil, you'll need another sentinel value:

[:one :two | | result marker |
    result := marker := Object new.
    (result == marker) ifTrue: ["do one thing, possibly setting result"].
    result]

最后-我很犹豫地建议您-您可以这样做:

Lastly - and I hesitate to suggest this - you could do this:

[1 + 2.
thisContext return: 5.
3 + 4] value

返回5.

(验证它如何与^和内嵌的选择器(如#ifTrue:ifFalse:)交互,作为读者的练习.)

(Verifying how this interacts with ^ and inlined selectors like #ifTrue:ifFalse: left as an exercise for the reader.)

这篇关于smalltalk块-我可以显式设置返回值并停止执行该块吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆