为什么明确的回报在Proc中有所作为?

def foo f = Proc.new { return "return from foo from inside proc" } f.call # control leaves foo here return "return from foo" end def bar b = Proc.new { "return from bar from inside proc" } b.call # control leaves bar here return "return from bar" end puts foo # prints "return from foo from inside proc" puts bar # prints "return from bar" 

我认为在Ruby中return关键字是可选的,并且无论您是否请求,您总是return 。 鉴于此,我发现foobar具有不同的输出,这是由fooProc f包含显式return这一事实决定的。

有谁知道这是为什么?

Ruby有三个构造:

  1. 不是一个对象,由{}doend
  2. proc是由Proc.newproc创build的Proc对象。
  3. lambda是由lambda创build的Proc (或者Ruby 1.8中的proc )。

Ruby有三个从某些东西返回的关键字:

  1. return终止方法或lambda它在。
  2. next终止它所在的块,proc或lambda。
  3. break终止产生到块的方法或调用它所在的proc或lambda。

在lambdaexpression式中,无论出于何种原因, return行为都像nextnextbreak是按照它们的方式命名的,因为它们通常与each方法一起使用,在这些方法中,终止块将导致迭代继续执行集合的下一个元素,并终止each元素将导致您跳出循环。


如果在foo的定义中使用return ,即使它在一个块或一个proc中,也将从foo返回。 要从块返回,可以使用next关键字。

 def foo f = Proc.new { next "return from foo from inside proc" } f.call # control leaves foo here return "return from foo" end puts foo # prints "return from foo" 

这是Proc的语义; 它不一定是所有块的语义。 我同意这有点混乱。 这是为了增加灵活性(也许部分导致Ruby除了实现之外没有规范)。

行为在Proc实现中定义。 Lambda的行为是不同的,所以如果你想让你的return 不能退出封闭的方法,请使用lambdas 。 或者,省略Procreturn关键字。

Rubysclosures的深入调查在这里 。 这是一个梦幻般的揭露。

所以:

 def foo f = Proc.new { p2 = Proc.new { return "inner proc"}; p2.call return "proc" } f.call return "foo" end def foo2 result = Proc.new{"proc"}.call "foo2 (proc result is: #{result})" end def bar l = lambda { return "lambda" } result = l.call return "bar (lambda result is: #{result})" end puts foo # inner proc puts foo2 # foo (proc result is: proc) puts bar # bar (lambda result is: lambda) 

想想这样:Proc.new只需创build一个代码块,这是调用函数的一部分。 proc / lambda创build一个具有特殊绑定的匿名函数。 一些代码示例将有所帮助:

 def foo f = Proc.new { return "return from foo from inside Proc.new" } f.call # control leaves foo here return "return from foo" end 

相当于

 def foo begin return "return from foo from inside begin/end" } end return "return from foo" end 

所以很明显,返回将从函数'foo'

相反:

 def foo f = proc { return "return from foo from inside proc" } f.call # control stasy in foo here return "return from foo" end 

相当于(忽略绑定,因为在这个例子中没有使用):

 def unonymous_proc return "return from foo from inside proc" end def foo unonymous_proc() return "return from foo" end 

这显然不会从foo返回,而是继续到下一个语句。