我今天遇到了这个问题并认为发布Q& A是谨慎的,因为我找不到类似的东西。
如果您发现此问题的副本,请随时投票决定。
以下子程序有条件地return
输出;我认为它“笨拙”,因为当条件不满足时,它不清楚返回给调用者的内容:
sub is_multiple_of_three {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
unless $value % 3;
}
快速重写可以在所有情况下简化(更优雅)子程序的预期行为:
sub is_multiple_of_three {
my ( $value ) = @_ ;
return if $value % 3;
return "$value is a multiple of 3";
}
当调用这两个子程序时,我希望在列表上下文中的return
之间找到一些一致性:
但是,唉,这种行为有些出乎意料:
use strict;
use warnings;
use Data::Printer;
use feature 'say';
my %subs = (
graceful => sub {
my ( $value ) = @_ ;
return if $value % 3;
return "$value is a multiple of 3";
},
clumsy => sub {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
unless $value % 3;
},
);
for my $name ( keys %subs ) {
my $sub = $subs{$name};
say $name;
my @results = map { $sub->($_) } 1 .. 10;
p @results;
}
输出
graceful
[
[0] "3 is a multiple of 3",
[1] "6 is a multiple of 3",
[2] "9 is a multiple of 3"
]
clumsy
[
[0] 1,
[1] 2,
[2] "3 is a multiple of 3",
[3] 1,
[4] 2,
[5] "6 is a multiple of 3",
[6] 1,
[7] 2,
[8] "9 is a multiple of 3",
[9] 1
]
问题
“graceful”风格的行为符合预期,但为什么“条件为假”时“笨拙”子返回整数?
答案 0 :(得分:5)
可以选择使用
return
语句来退出子例程 指定返回值,将在。中计算 适当的上下文(列表,标量或无效)取决于上下文 子程序调用。 如果指定无返回值,则子例程 返回列表上下文中的空列表 ,标量中的未定义值 上下文,或无空间背景中的任何内容如果您返回一个或多个 聚合(数组和散列),这些将被拼合成 一个无法区分的大名单。如果 未找到任何返回,并且最后一个语句是表达式,则返回其值 。如果最后一个语句是循环控制结构,如
foreach
或while
,则返回的值未指定。空子返回空列表。
优雅的列表上下文:
True :返回字符串"$value is a multiple of 3"
已返回
错误:返回空列表
这就是@results
中只有三个元素的原因;只有当条件计算结果为true时,才会向数组添加某些内容。
列表上下文中的笨拙子:
"$value is a multiple of 3"
。这里没有戏剧。return
,因此返回上次评估的表达式的值$value % 3
因此,在这两种情况下,子程序都会返回一个值,这就是@results
中有十个项目的原因。
答案 1 :(得分:1)
出于最后表达的目的,foo if bar
和if (bar) { foo }
等同于bar and foo
,同样,除非等同于或。