我想将两个参数传递给我的子程序。第一个参数是必需的,第二个参数我想是可选的。实际上它适用于此脚本中的非数组参数:
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";
}
当我用(“字符串值测试”,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个。)
为什么它不适用于数组?
答案 0 :(得分:3)
因为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根本无法判断最后一个数字是否是您发送的列表的一部分,或者是一个可选参数。
答案 1 :(得分:2)
子例程的参数是Perl中的列表。将参数分配给数组时,Perl不知道该数组应该有多长,因此无法执行此操作:
sub frobnicate {
my (@foo, $bar) = @_;
}
在这种情况下,$bar
始终为undef
,因为它只是将列表的其余部分分配给@foo
。
相反,您需要将参数的数组部分作为引用,并正确地对其进行反驳。
sub frobnicate {
my ($foo, $bar) = @_;
foreach my $element (@{ $foo }) {
# ...
}
}
然后用引用来调用它。
frobnicate(\@foo, 123);
因为引用是标量值,所以现在您知道参数列表中有多少个元素,并且您可以在列表的末尾添加可选参数。
答案 2 :(得分:2)
数组在参数列表中展开,形成前N个参数,最后出现$num
如果以这种方式传递数组,则无法从子例程中判断出数组中有多少参数,因此最好通过 reference 传递数组
您的代码看起来像这样
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