为什么下面的代码没有返回任何输出?我期待它打印出“包含”。
sub is_member {
my ($x, @list) = @_;
foreach (@list) {
if ($x eq $_) {"contains"} else {"doesn't contain"}
}
}
my @a = qw(apple x orange but so nos how dod to it a b c);
print is_member("apple",@a)."\n";
如下面的代码运行正常,输出“is palindrome”
sub is_palindrome {
my ($x) = @_;
if ($x eq reverse($x)){"is palindrome"} else {"Not a palindrome"}
}
print is_palindrome("radar")."\n";
答案 0 :(得分:6)
此代码:
if ($x eq $_) {"contains"} else {"doesn't contain"}
不会打印或返回任何内容。它评估两个常量,但这就是全部。我很惊讶没有关于丢失分号的投诉。缩进是古怪的。
你可能想要更像的东西:
sub is_member
{
my ($x, @list) = @_;
foreach (@list)
{
return "contains" if ($x eq $_);
}
return "doesn't contain";
}
答案 1 :(得分:2)
for
个循环没有返回值。在is_palindrome
中,if
语句由其自身计算,它隐式生成子例程的返回值。
对于for
循环,即使在for循环中评估的最后一个语句成为返回值,最后一次比较"apple" eq "c"
也将为false。
如果您想使用for
循环进行测试,则需要exit the loop early。但是,在Perl中,grep
是测试列表元素是否满足条件的内置方法。
my $result = (grep $_ eq $x, @list) ? "contains" : "does not contain";
print "'@list' $result $x\n";
如果您只对某个元素的存在感兴趣,List::MoreUtils::any 并且List::MoreUtils::first_index在列表很长的情况下提供了性能优势。
conditional operator,$cond ? $t : $f
对于编写紧凑条件非常有用,而不是尝试在带有大括号和所有大括号的单行上拟合if
语句。
答案 2 :(得分:0)
澄清subs的返回值,默认情况下,Perl返回sub中最后一个表达式的求值的值...除非它在循环中。来自perldoc:
如果没有找到返回,并且最后一个语句是表达式,则为 返回值。如果最后一个语句是循环控制结构 像foreach或while,返回值未指定。该 empty sub返回空列表。
但正如其他人所说,如果您要返回任何内容,则应始终使用return
,以获得可读性和稳定性。
你的潜艇是不必要的也是如此。 grep
将在标量上下文中返回0或1(可以用作布尔值),或者在数组上下文中返回新的匹配值数组;例如:
my @a = qw(apple x orange but so nos how dod to it a b c);
print "found" if grep /^orange$/, @a; # prints "found"
my @b = grep length > 3, @a;
print "@b" # prints "apple orange"