题
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有三个结构:
- 块不是对象,由
{
...}
或do
创建。 。end
。 - proc 是由
Proc.new
或proc
创建的Proc
对象。 - lambda 是由
lambda
(或Ruby 1.8中的proc
)创建的Proc
。
醇>
-
return
终止它所在的方法或lambda。 -
next
终止它所在的块,proc或lambda。 -
break
终止产生于块的方法或调用它所在的proc或lambda。
醇>
Ruby有三个从某些东西返回的关键字:
在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返回并继续下一个语句。
不隶属于 StackOverflow