执行
的子程序之间是否存在差异?return;
还有一个吗?
return undef;
答案 0 :(得分:48)
return;
将在列表上下文中返回一个空列表,但在标量上下文中返回undef
。 return undef;
即使在列表上下文中也会始终返回单个值undef
。
一般来说,通常在列表上下文中通常使用的子例程return undef;
不是一个好主意:
sub foo { return undef }
if ( my @x = foo() ) {
print "oops, we think we got a result";
}
一般来说,通常在标量上下文中通常使用的子例程return;
通常不是一个好主意,因为它不会像用户在列表上下文中所期望的那样运行:
sub foo { return }
%x = ( 'foo' => foo(), 'bar' => 'baz' );
if ( ! exists $x{'bar'} ) {
print "oops, bar became a value, not a key";
}
这两个错误在实践中都发生了很多,后者更是如此,也许是因为预期返回标量的sub更常见。如果预计返回标量,最好返回标量。
答案 1 :(得分:21)
鉴于
sub foo { return; }
sub bar { return undef; }
在标量上下文中,它们的行为相同。
my $foo = foo(); # $foo is undef
my $bar = bar(); # $bar is undef
在列表上下文中,它们的行为方式不同
my @foo = foo(); # @foo is () (an empty list)
my @bar = bar(); # @bar is ( undef ) (a one-element list)
请注意,单元素列表在布尔上下文中是真值,即使唯一元素是undef
。
一般来说,return undef;
从子程序中通常不是一个好主意,因为它在上下文中的行为方式。
答案 2 :(得分:2)
我认为我仍然同意PBP。
1)你应该避免嵌套函数调用:
my $result = bar();
foo(1, $result, 2);
2)你应该始终明确(做“复杂”事情时):
foo(1, scalar bar(), 2);
答案 3 :(得分:2)
这本书" Perl最佳实践"建议使用return;
而不是return undef;
,因为后者会在列表上下文中返回单元素列表(其他答案已经提到了这一点)。这将是一个令人讨厌的错误"根据这本书。
但是,我认为什么都不返回会导致严重的错误(可能很难找到),而在列表上下文中调用布尔函数似乎很容易调试。
所以我总是在我的布尔函数中返回某些(评估为)false(通常0表示false,1表示true)。
(是的,这也会在列表上下文中返回一个单元素列表 - 所以书中的注释在技术上是正确的 - 但实际的错误是在列表上下文中调用布尔函数。)
要清楚,我仍然推荐这本书。它提供了很多很好的建议 我指的是第9章(子程序),第199/200页("使用一个简单的回报来返回失败。")在书中#Per; Perl Best Practices"由Damian Conway(O' Reilly Media,Inc。),ISBN 978-0-596-00173-5。不确定是否有其他/更新的版本。
旁注:
当否定某些东西时,Perl似乎返回一个空字符串。 my $foo = 5; return !$foo;
会返回q()
。