如何将可选参数传递给 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
我想将两个参数传递给我的子例程。第一个参数是必需的,第二个参数我想是可选的。实际上它适用于此脚本中的非数组参数:
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