从不是例程的块中从CATCH移相器返回值的语法是什么?
sub foo() {
<1 2 3>.map: -> $a {
die 'oops';
CATCH { default { 'foo' } }
}
}
sub bar() {
<1 2 3>.map: -> $a {
die 'oops';
CATCH { default { return 'bar' } }
}
}
say foo(); # (Nil, Nil, Nil)
say bar(); # Attempt to return outside of immediatelly-enclosing Routine (i.e. `return` execution is outside the dynamic scope of the Routine where `return` was used)
编辑:所需的输出是:
say baz(); # (baz baz baz)
用例是map
Seq
一个方法,它间歇性地抛出异常,通过返回默认值来处理传递给map的块内的异常。
答案 0 :(得分:8)
返回退出功能范围,但在bar()
中使用它的方式有两种功能在起作用。
bar()
方法本身。这意味着你的回归含糊不清(好吧,至少对某些人而言),编译器会不肯。
没有&#34;返回&#34; foo()
中的值作为块内的常量处理,块返回Nil。这意味着在foo()
中,您有效地避免了解析return
的含义,有效地在堆栈上推送Nil
。
这就是为什么在Nil
的捕获输出中有3个foo()
s的原因。对于bar()
,目前还不清楚您是否希望在第一个抛出的异常上终止执行bar()
例程,或者您是否只想将'bar'
作为非Nil
传递回去将CATCH块压入堆栈。
代码的略微修改版
#!/bin/env perl6
sub foo() {
<1 2 3>.map: -> $a {
die 'oops';
}
CATCH { default { 'foo' } }
}
sub bar() {
<1 2 3>.map: -> $a {
die 'oops';
}
CATCH { default { return 'bar' } }
}
say foo();
say bar();
可能会使这一点更加明确。它的输出是
[edwbuck@phoenix learn_ruby]$ ./ed.p6
Nil
bar
答案 1 :(得分:3)
这里发生的是懒惰列表导致控制流不明显。
你的两个函数的返回值是一个Seq,它的值是通过依次调用值a,b和c上的小lambda生成的。知道了这一点,就很容易理解为什么你不能改变bar
的返回值:bar
已经在你的lambda第一次被调用之前已经返回了。列表为say
d后,将生成所有值并抛出异常。
获得所需内容的正确方法是在地图结果上调用.eager,从而在函数返回之前评估整个列表,这样您就可以使用return
来更改值bar
返回。