这就是我所期待的.fib(13)返回233.
sub fib(Int $a --> Int) {
return 0 if $a == 0;
return 1 if $a == 1;
return fib($a -1) + fib($a -2);
}
my $square = -> $x { $x * 2 }; # this works with no return value
my @list = <1 2 3 4 5 6 7 8 9>.map( $square );
# returns [2 4 6 8 10 12 14 16 18]
Run Code Online (Sandbox Code Playgroud)
我尝试使用匿名子实现fib()
my $fib = -> Int $x --> Int {
return 0 if $x == 0;
return 1 if $x == 1;
return $fib($x - 1) + $fib($x - 2);
}
$fib(13)
Run Code Online (Sandbox Code Playgroud)
使用显式返回运行时出现以下错误.
尝试在test.p6第39行的块中返回任何例程
所以我摆脱了返回值.
my $fib = -> Int $x --> Int {
0 if $x == 0;
1 if $x == 1;
$fib($x - 1) + $fib($x - 2);
}
say $fib(13);
Run Code Online (Sandbox Code Playgroud)
最后一个版本永远不会返回 有没有办法编写一个没有返回值的匿名递归函数?
根据文件:
不是Routine类型的块(它是Block的子类)对于返回是透明的.
Run Code Online (Sandbox Code Playgroud)sub f() { say <a b c>.map: { return 42 }; # ^^^^^^ exits &f, not just the block }
最后一个语句是块的隐式返回值
所以你可以尝试:
my $fib = -> Int $x --> Int {
if ( $x == 0 ) {
0; # <-- Implicit return value
}
elsif ( $x == 1 ) {
1; # <-- Implicit return value
}
else {
$fib($x - 1) + $fib($x - 2); # <-- Implicit return value
}
}
Run Code Online (Sandbox Code Playgroud)
还有三个选择:
sub
您可以通过使用没有名称来编写匿名例程sub
:
my $fib = sub (Int $x --> Int) {
return 0 if $x == 0;
return 1 if $x == 1;
return $fib($x - 1) + $fib($x - 2);
}
say $fib(13); # 233
Run Code Online (Sandbox Code Playgroud)
请参阅@HåkonHægland的答案,了解为什么这(故意)不适用于非常规块.
leave
设计预计了你的问题:
my $fib = -> Int $x --> Int {
leave 0 if $x == 0;
leave 1 if $x == 1;
leave $fib($x - 1) + $fib($x - 2);
}
Run Code Online (Sandbox Code Playgroud)
编译.希望你能猜到它的作用 - 或者更确切地说应该做的 - 正是你想要做的.
不幸的是,如果你按照上面的说法:
say $fib(13);
Run Code Online (Sandbox Code Playgroud)
你得到一个运行时错误"还没有实现".
我的猜测是,这将在未来几年内实施一段时间,然后提及"尝试返回任何常规"错误消息leave
.但是实现它的优先级非常低,因为它很容易sub
按上面的方式编写,或者像@HåkonHægland那样编写代码,或者使用case/switch语句结构,如下所示,现在已经足够好了.
when
/ default
)您可以指定参数$_
而不是,$x
然后您将全部设置为使用引用该主题的构造:
my $fib = -> Int $_ --> Int {
when 0 { 0 }
when 1 { 1 }
$fib($_ - 1) + $fib($_ - 2)
}
say $fib(13); # 233
Run Code Online (Sandbox Code Playgroud)
见when
.