11

我在理解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.
4

2 回答 2

9

正如链接问题中的一个答案所示:

return关键字总是从当前上下文中的方法或 lambda 返回。在块中,它将从定义闭包的方法返回。它不能从调用方法或 lambda 中返回。

您的第一个示例是成功的,因为您victor在要从中返回的同一函数中定义,因此 areturn在该上下文中是合法的。在您的第二个示例中,victor是在顶层定义的。return那么,that 的效果不会是从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.
于 2013-03-22T05:20:51.160 回答
1

我来自 C 背景,我将解释它的方式是,当您调用一个函数时,您会设置一个返回指令号和一个将存储返回值的寄存器。在 proc 和 block 的情况下,没有设置返回指令,因为它们是在同一范围内内联或调用的,但它们仍然可以返回返回值,因为它们是独立的功能。因此,如果没有设置返回指令,proc/block 会给我们一个 LocalJumpError,而如果我们只想返回一个值,那很好。

于 2015-07-01T02:41:45.293 回答