回报有什么区别;并返回undef;在Perl

时间:2010-08-08 16:36:25

标签: perl

执行

的子程序之间是否存在差异?
return;

还有一个吗?

return undef;

4 个答案:

答案 0 :(得分:48)

return;将在列表上下文中返回一个空列表,但在标量上下文中返回undefreturn 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()