返回 procs、lambdas 和 blocks 中的语句
Posted
技术标签:
【中文标题】返回 procs、lambdas 和 blocks 中的语句【英文标题】:Return statements inside procs, lambdas, and blocks 【发布时间】:2013-03-11 20:54:34 【问题描述】:我很难理解 return
如何在块、procs 和 lambdas 中工作。
例如,在以下情况下,为什么batman_ironman_proc
工作,而batman_yield
抛出错误?
def batman_ironman_proc
victor = Proc.new return "Batman will win!"
victor.call
"Iron Man will win!"
end
def batman_yield
yield
"Iron man will win!"
end
victor = Proc.new return "Batman will win!"
puts batman_ironman_proc
#batman_yield(&victor) === This code throws an error.
【问题讨论】:
Using 'return' in a Ruby block 的可能重复项 这里:***.com/questions/1435743/… 我知道你正在从 codeacademy 学习这个。我也有同样的疑问。这是一个不错的入门教程,但你必须在谷歌上搜索很多才能理解教程。 【参考方案1】:正如链接问题中的one answer 所示:
return
关键字总是从当前上下文中的方法或 lambda 返回。在块中,它将从 定义 闭包的方法返回。它不能从 调用 方法或 lambda 中返回。
您的第一个示例是成功的,因为您在想要返回的同一个函数中定义了victor
,因此return
在这种情况下是合法的。在您的第二个示例中,victor
是在顶层定义的。那么,return
的效果将不是从 batman_yield
(调用方法)返回,而是 [如果它有效] 从顶层本身返回(其中Proc
已定义)。
澄清:虽然您可以访问块的返回值(即“块中评估的最后一个表达式的值作为产量的值传递回方法” - 如根据您的评论),由于上述原因,您不能使用 return
关键字。示例:
def batman_yield
value = yield
return value
"Iron man will win!"
end
victor = Proc.new return "Batman will win!"
victor2 = Proc.new "Batman will win!"
#batman_yield(&victor) === This code throws an error.
puts batman_yield(&victor2) # This code works fine.
【讨论】:
鉴于这种情况,find等接受逻辑测试块的方法如何使用这些逻辑测试的结果? (例如:[1,2,3,4,8,10].find |num| num*num>24) @user1419674 查看更新后的答案。与您的示例代码没有使用return
的方式相同,您也不必使用它来访问块的评估。您可以只使用来自call
的返回值,直接使用它(如在我的示例代码中)或将其分配给变量(例如:value = block.call
)
这对我来说很奇怪,但我相信这个链接可以回答这个问题。 [链接]ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html其实说yield可以提供返回值。让我感到奇怪的是,在这种情况下,显式返回和隐式返回似乎会在块内产生不同的结果。
这里是链接的相关摘录:“块也可以将值返回给方法。块中计算的最后一个表达式的值作为yield。这就是类 Array 使用的 find 方法的工作原理。[find 方法实际上是在模块 Enumerable 中定义的,它被混合到类 Array 中。]它的实现如下所示。"
@user1419674 感谢您指出yield
可以返回一个值,我更新了答案。关于“奇怪”,我对这个功能也有这种感觉,但至少规范是明确的:return
关键字是相对于 定义 上下文,而不是 调用 i> 一个。【参考方案2】:
我来自 C 背景,我将解释它的方式是,当您调用一个函数时,您会设置一个返回指令号和一个将存储返回值的寄存器。在 proc 和 block 的情况下,没有设置返回指令,因为它们是在同一范围内内联或调用的,但它们仍然可以返回返回值,因为它们是独立的功能。因此,如果没有设置返回指令,proc/block 会给我们一个 LocalJumpError,而如果我们只想返回一个值,那很好。
【讨论】:
以上是关于返回 procs、lambdas 和 blocks 中的语句的主要内容,如果未能解决你的问题,请参考以下文章
proc、Proc.new、lambda 和 stabby lambda 之间的速度差异
什么是 procs 和 lambdas?请提供实际示例[重复]