[英]Perl Passing arguments to subroutine not working
我試圖將參數傳遞給perl子例程,無論出於何種原因,該子例程中的參數都為空。
...
...
...
print "Passing arguments $a, $b, $c, $d \n";
beforeEnd($a, %b, $c, $d);
sub beforeEnd() {
my ($a, %b, $c, $d) = @_;
print "a is $a, b is $b, c is $c, d is $d \n";
}
打印語句的輸出使我知道出了點問題。 奇怪的部分? 前兩個參數正確傳遞。
> Passing arguments 1, (1,2,3), 2, 3
> a is 1, b is (1,2,3), c is , d is
任何幫助將不勝感激。
因為當您將參數傳入或傳出子例程時,所有哈希和數組都會被粉碎平整。
您正在分配給%b
,它將吞噬所有參數。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
sub test1 {
my ( $first, @rest, $last ) = @_;
print Dumper \@rest;
print "First = $first, last = $last, rest = @rest\n";
}
sub test2 {
my ( $first, $second ) = @_;
print "@$first ; @$second";
}
test1 ( 1, 2, 3, 4 );
test2 ( [1,2], [ 3,4] );
my @list1 = ( 1,2,3,4 );
my @list2 = ( 5,6,7,8 );
test1 ( @list1, @list2 );
test2 ( \@list1, \@list2 );
如果要保持數組或哈希完整無缺,則需要通過引用或作為最后一個參數傳遞它們。
如果在此處啟用strict
警告,您也可能會得到warnings
-這是強烈建議使用的原因之一-因為$b
和%b
不相同。 您還會收到有關奇數作業的警告:
Odd number of elements in hash assignment at line 5.
Use of uninitialized value $b in print
當參數傳遞給Perl子例程時,它們被展平為@_
表示的單個List。 從概念上講,這意味着如果您不傳遞對數組或哈希的引用,則會“丟失”某些數據。 “丟失”並不完全正確,因為所有數據仍然存在。 它只是不在您期望的變量中。 例如:
sub f {
my (@a, @b) = @_;
say 'a: ' . join(', ', @a);
say 'b: ' . join(', ', @b);
}
f( qw(1 2 3), qw(a b c) );
您將獲得以下輸出:
a: 1, 2, 3, a, b, c
b:
發生這種情況是因為第一個數組@a
消耗了@_
所有值,並且沒有@b
存儲在@b
。 您的beforeEnd子例程中的哈希發生了相同的事情。 $c
和$d
的值存儲在%b
。 作為一個例子,因為如果您通過了,我看不到變量值
beforeEnd(1, ( a => 1, b => 2 ), 'c', 3);
在您的子目錄中,您得到的是這樣的:
$a = 1
%b = ( a => 1, b => 2, c => 3 )
$c = undef
$d = undef
您可以通過傳遞對哈希%b的引用來解決此問題:
beforeEnd($a, \%b, $c, $d);
子例程接受標量列表作為參數。 如果傳遞數組或哈希,則將傳遞數組或哈希的內容。 那意味着
f($a, %b, $c, $d)
是相同的
f($a, $b_key_1, $b_val_1, $b_key_2, $b_val_2, $b_key_3, $b_val_3, $c, $d);
@_
應將多少個標量分配給%b
? Perl保持簡單,並分配所有剩余的標量,因此
my ($a, %b, $c, $d) = @_;
真的沒有什么不同
my $a = $_[0]; # The first argument
my %b = @_[1..$#_]; # All but the first argument
my $c;
my $d;
最好是傳遞對哈希的引用。 這樣可以避免問題,並且效率更高。
use Data::Dumper qw( Dumper );
sub beforeEnd {
my ($a, $b, $c, $d) = @_;
local $Data::Dumper::Terse = 1;
print "a is $a, b is ".Dumper($b).", c is $c, d is $d \n";
}
beforeEnd($a, \%b, $c, $d);
關於您的代碼的離題注釋:
您有一個原型,指示沒有期望的參數()
,但您希望有四個。 讓自己擺脫那個原型。
您應該避免將$a
和$b
用作變量,因為它可能會與sort
。
這些參數只能作為標量變量列表在子例程中傳遞。
每當將參數傳遞給子例程時,我們都需要傳遞哈希(或數組,對象)的引用。 ……打印“傳遞參數$ a,$ b,$ c,$ d \\ n”; beforeEnd($ a,\\%b,$ c,$ d);
sub beforeEnd() {
my ($a, $b, $c, $d) = @_;
print "a is $a, b is %$b, c is $c, d is $d \n";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.