如何将可选参数传递给 Perl 子例程?

How to pass optional parameters to a Perl subroutine?

我想将两个参数传递给我的子例程。第一个参数是必需的,第二个参数我想是可选的。实际上它适用于此脚本中的非数组参数:

            deftest ("string value test",9);

            sub deftest{
                my ($strvalue, $num) = @_;
                if (defined $num){
                    print "\nCHECK 1 - Defined value $num";
                } else {
                    $num //= 99;
                }
                print "\nstrvalue: $strvalue num: $num\n";
            }

当我用 ("string value test",9) 调用这个子程序时;然后在屏幕上:
CHECK 1 - Defined value 9 strvalue: string value test num: 9

当我不输入第二个参数时,该值为 99。因此可以正常工作。

问题是,当我在第一个参数中使用数组时:

            my @arrSwap = (1,2,3);
            deftest2 (@arrSwap,5);

            sub deftest2{
                my (@arrSwap, $num) = @_;
                if (defined $num){
                    print "\n\nCHECK 2 - Defined val $num";
                } else {
                    $num //= 55;
                }
                print "\narrSwap $arrSwap[1] num: $num\n";
            }

用deftest2(@arrSwap,5)调用这个子程序后;然后在屏幕上我只有:arrSwap 2 num: 55 (但按定义应为 5)。

为什么它不适用于数组?

子例程的参数是 Perl 中的列表。当您将参数分配给一个数组时,Perl 不知道该数组应该有多长,所以没有办法做到这一点:

sub frobnicate {    
    my (@foo, $bar) = @_;
}

在那种情况下,$bar 将始终是 undef,因为它只是将列表的其余部分分配给 @foo

相反,您需要将参数的数组部分设为引用,并正确取消引用。

sub frobnicate {
    my ($foo, $bar) = @_;

    foreach my $element (@{ $foo }) {
        # ...
    }
}

然后用引用调用它。

frobnicate(\@foo, 123);

因为引用是标量值,所以您现在知道参数列表中有多少元素,并且列表末尾可以有可选参数。

因为 perl 将 单个 列表作为参数传递,并且分配 my ( @arrSwap, $num ) = @_总是 意味着空 $num,因为 @arrSwap 将消耗整个输入。

如果你想这样做,你需要传递一个引用

    my @arrSwap = ( 1,2,3 ); 
    deftest2 ( \@arrSwap, 5);  

    sub deftest2 { 
        my ( $arrSwap_ref, $num ) = @_; 
        $num //= 55;
        print "\narrSwap", $arrSwap -> [1], " num: $num\n";
    }

否则 perl 根本无法判断最后一个数字是您发送的列表的一部分,还是一个可选参数。

数组在参数列表中展开,形成前N个参数,$num出现在末尾

如果以这种方式传递数组,则无法从子例程中判断有多少参数来自数组,因此最好始终通过 reference[=24 传递数组=]

您的代码如下所示

my @arrSwap = ( 1, 2, 3 );

deftest2( \@arrSwap, 5 );
deftest2( \@arrSwap );

sub deftest2 {
    my ( $arrSwap, $num ) = @_;

    if ( defined $num ) {
        print "\n\nCHECK 2 - Defined val $num";
    }
    else {
        $num = 55;
    }
    print "\narrSwap $arrSwap->[1] num: $num\n";
}

输出

CHECK 2 - Defined val 5
arrSwap 2 num: 5

arrSwap 2 num: 55