我注意到如果我在块中使用关键字return
,则返回整个方法。我发现令人困惑的是,在ruby中,你可以选择使用return
关键字 - 它就像:“那么这件事又回来了什么?如果有的话?开发人员是否打算让这个方法返回一些东西?”所以我喜欢在内部块中使用return
,例如:
def my_method
items = [ 1, 2, 3 ]
items_times_ten = items.collect { |o|
#multiple
#lines
#of
#code ...
return o * 10 # Ruby exits the method at this point.
}
return items_times_ten #This is never reached.
end
我理解为什么我不需要从块中返回,但如果我的块更复杂,那么它似乎有助于清晰。我的问题是,为什么Ruby会假设我想将控制权退出两个级别?
如果我的假设不正确,请纠正我。我只是想了解以这种方式处理控制的原因。
答案 0 :(得分:3)
这是一个块/ Proc和lambda / Method之间的主要区别之一(另一个主要区别是arity)。如果您不希望调用return
来退出该方法,那么这将推断您希望该块应该在其流控制中自包含,并被视为封装方法。
这个描述本质上是一个lambda - 一个匿名方法。但是,标准的ruby块本质上是一个匿名的Proc,并且不会从该方法的流控制中获取任何东西。
如评论中所述,您可以使用next
来逃避阻止,而无需将控制权从方法中移开。 'May'因为next
可能只是继续到方法迭代器传递给块的下一个项目。
与此相关,请参阅http://yehudakatz.com/2012/01/10/javascript-needs-blocks/和Differences between Proc and Lambda
答案 1 :(得分:2)
如果您将某个块视为某种嵌套函数或匿名方法,那么您希望return
使该块成为产生它的迭代器。但块是不是方法。 return
总是会导致封闭方法返回,无论它在块内嵌套的程度有多深。
答案 2 :(得分:1)
您所看到的行为可以通过Procs
和Lambdas
在return
关键字的上下文中在ruby中的行为来解释。
例如,以下内容为您提供了预期的结果:
def my_method
items = [ 1, 2, 3 ]
a = ->(o){return o * 10} # lambda
items_times_ten = items.collect(&a)
return items_times_ten #This is never reached.
end
p my_method # [10, 20, 30]
基本上,return
中的Proc
会停止某个方法并返回提供的值,而另一方面Lambdas
会return
将其值设置为该方法。< / p>
另一种解决方法是,如果您仍想使用Proc
,则使用隐式return
。例如:
def my_method
items = [ 1, 2, 3 ]
items_times_ten = items.collect { |o|
o * 10 # Removed the explicit return
}
return items_times_ten #This is never reached.
end
p my_method # [10, 20, 30]