perl - 当没有遇到 return 语句时,Perl 从子例程返回什么?

标签 perl

我今天遇到了这个问题,并认为发布问答是明智的,因为我找不到任何类似的东西。
如果您发现此问题的重复,请随时投票关闭。

以下子程序有条件地 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
    ]
    

    问题

    “优雅”风格的行为符合预期,但为什么“笨拙”子在条件为假时返回整数?

    最佳答案

    该行为与 perldoc perlsub 中记录的内容一致

    A return statement may be used to exit a subroutine, optionally specifying the returned value, which will be evaluated in the appropriate context (list, scalar, or void) depending on the context of the subroutine call. If you specify no return value, the subroutine returns an empty list in list context, the undefined value in scalar context, or nothing in void context. If you return one or more aggregates (arrays and hashes), these will be flattened together into one large indistinguishable list.

    If no return is found and if the last statement is an expression, its value is returned. If the last statement is a loop control structure like a foreach or a while , the returned value is unspecified. The empty sub returns the empty list.



    列表上下文中的优雅子 :
  • True : 返回字符串 "$value is a multiple of 3"被退回
  • False : 返回一个空列表

  • 这就是为什么 @results 中只有三个元素的原因;仅当条件评估为真时才将某些内容添加到数组中。

    列表上下文中的笨拙子 :
  • True : 返回字符串 "$value is a multiple of 3"被退回。这里没有戏剧。
  • 假:因为没有明确 return遇到,返回最后一个表达式的值,$value % 3

  • 所以在这两种情况下,子程序都会返回一个值,这就是为什么@results里面有十个项目。

    关于perl - 当没有遇到 return 语句时,Perl 从子例程返回什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45154101/

    相关文章:

    perl - 在 Perl 中实现函数式编程

    perl - 从 Perl 模块导出所有常量(只读变量)的最有效方法是什么

    xml - 使用 Perl 解析 XML

    perl - 确定日期范围内的日期的好方法是什么?

    regex - Bash 正则表达式字符串变量匹配

    linux - NET::SSH2 带 sudo

    regex - 为什么 `perl -pe ' s/$/\n/g'` 添加 2 个空行?

    regex - perl 正则表达式不匹配带有换行符的字符串\n

    perl - 如何在 Perl 中解析 .pdf 文件?

    在 Perl 中解压 32 位 vector 以读取用 C 编写的 uint32 的正确方法