代码之家  ›  专栏  ›  技术社区  ›  friedo

在Perl中,return和return-undef有什么区别?

  •  26
  • friedo  · 技术社区  · 14 年前

    有没有不同的子程序

    return;
    

    还有一个呢?

    return undef;
    
    4 回复  |  直到 14 年前
        1
  •  48
  •   brian d foy    10 年前

    return; 将在列表上下文中返回空列表,但 undef 在标量上下文中。 return undef; 将始终返回单个值 解脱 即使在列表上下文中。

    一般来说,这通常不是一个好主意 返回; 来自通常在列表上下文中使用的子例程:

    sub foo { return undef }
    if ( my @x = foo() ) {
        print "oops, we think we got a result";
    }
    

    一般来说,这通常不是一个好主意 返回; 来自通常在标量上下文中使用的子例程,因为它的行为不会像用户在列表上下文中期望的那样:

    sub foo { return }
    %x = ( 'foo' => foo(), 'bar' => 'baz' );
    if ( ! exists $x{'bar'} ) {
        print "oops, bar became a value, not a key";
    }
    

    这两个错误在实践中都会发生很多,后者更是如此,可能是因为期望返回标量的sub更常见。如果期望它返回一个标量,最好返回一个标量。

        2
  •  21
  •   friedo    14 年前

    鉴于

    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; 因为它在上下文中的行为。

        3
  •  2
  •   nicomen    14 年前

    不过我还是同意PBP的观点。

    1)应避免嵌套函数调用:

    my $result = bar();
    foo(1, $result, 2);
    

    2)你应该始终明确(在做“复杂”的事情时):

    foo(1, scalar bar(), 2);
    
        4
  •  2
  •   pevik Hudson    6 年前

    “Perl最佳实践”一书建议使用 return; 而不是 return undef; 因为后者会在列表上下文中返回一个元素列表(其他答案已经提到了这一点)。根据这本书,这是一个“讨厌的虫子”。

    但是,我认为返回Nothing实际上会导致严重的错误(可能很难找到),而在列表上下文中调用布尔函数似乎很容易调试。

    所以我 总是 返回 某物 (计算结果为)在布尔函数中为假(通常为0表示假,1表示真)。
    (是的,这还将在列表上下文中返回一个元素列表-所以本书中的注释在技术上是正确的-但是实际的错误是在列表上下文中调用布尔函数。)

    很明显,我还是推荐这本书。它提供了很多好的建议。
    我指的是Damian Conway(O'Reilly Media,Inc.),ISBN 978-0-596-00173-5在《Perl最佳实践》一书中的第9章(子程序),第199/200页(“使用裸返回返回失败”)。不确定是否有其他/更新版本。

    边注:
    当否定某些内容时,Perl似乎返回空字符串。 my $foo = 5; return !$foo; 收益率 q() .