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" 

我认为 return 关键字在Ruby中是可选的,并且无论您是否请求,您始终 return 。鉴于此,我发现令人惊讶的是 foo bar 具有不同的输出,这是由 foo 包含显式的返回 Proc f 中。

有谁知道为什么会这样?

有帮助吗?

解决方案

Ruby有三个结构:

  1. 不是对象,由 { ... } do 创建。 。 end
  2. proc 是由 Proc.new proc 创建的 Proc 对象。
  3. lambda 是由 lambda (或Ruby 1.8中的 proc )创建的 Proc
  4. Ruby有三个从某些东西返回的关键字:

    1. return 终止它所在的方法或lambda。
    2. next 终止它所在的块,proc或lambda。
    3. break 终止产生于块的方法或调用它所在的proc或lambda。
    4. 在lambdas中,无论出于何种原因, return 的行为类似于 next next break 以它们的方式命名,因为它们最常用于 each 等方法,其中终止块将导致迭代到继续使用集合的 next 元素,并终止每个将导致中断退出循环。


      如果在 foo 的定义中使用 return ,则将从 foo 返回,即使它位于块或proc中。要从块返回,您可以使用 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 s的语义;它不一定是所有块的语义。我同意这有点令人困惑。它是为了增加灵活性(也许部分原因导致Ruby没有规范,除了它的实现)。

行为在 Proc 实现中定义。 Lambda 的行为有所不同,因此如果您希望返回不要退出,请使用 lambdas 。或者,忽略 Proc 中的 return 关键字。

对Rubys关闭的深入调查就在这里。这是一个很棒的展示。

所以:

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只是创建一个代码块,它是调用函数的一部分。 proc / lambda创建一个具有特殊绑定的匿名函数。一些代码示例将有所帮助:

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返回并继续下一个语句。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top