【perl】函式的引數變數和返回值
函式返回值
在Perl中,return語句可以返回一個標量值或者一個列表,這個標量值可以是一個變數,或者一個表示式的最後求值,如:return 1;<===>return(1); return $a+$b; <===>return($a+$b);
一個Perl函式的返回值,並不止一個,有時會有多個值需要返回,這時就要用到列表,這個列表可以包含多個變數值。
返回單一變數
subget_value() { my $var; $var=1; return($var); } my $result; $result = get_value(); print "\$result = $result \n";
返回多個標量
subget_value() {
my($var_a,$var_b);
$var_a=1;
$var_b=2;
return($var_a,$var_b);
}
my ($result_a,$result_b);
($result_a,$result_b) = get_value();
返回多個陣列
sub get_value()
{
my(@$var_a,@var_b);
@var_a=(1,2);
@var_b=(30,40);
return(\@var_a,\@var_b);
}
my (@result_a,@result_b);
my ($result_a_ref,$result_b_ref);
($result_a_ref,$result_b_ref)=get_value();
#here need to encode the reference
@ [email protected]$result_a_ref;
@[email protected]$result_b_ref;
print"\@[email protected]_a\n\@[email protected]_b\n";
#######print resultis:
@result_a=1,2
@result_b=30,40
引數中傳遞陣列
sub getarrays{ my(@a,@b) = @_; # @_ 是預設的包含本函式所有引數 ... } @fruit = qw(apples oranges banana); @veggies = qw(carrot cabbage turnip); getarrays(@fruit, @veggies);
預期 @fruit 會賦值給@a,@veggies賦值給@b,其實不然。
在呼叫getarrays(@fruit, @veggies)時,其把引數@fruit 和 @veggies壓縮到單個數組@_中。
這樣在getarrays函式內部,就會把@_賦值給@a,即@fruit和@veggies都賦值給@a.
傳遞引數引用可以很好的解決這個問題。即我們沒有必要傳遞整個陣列,只要傳遞相關陣列的引用就可以了。
引用一律宣告為標量型別(即$開頭的命名變數),使用\運算子取引用
對引用變數的修改等同於對引用指向實際資料的修改
取標量變數引用:my $scalar_r = \$scalar;
取列表的引用:my $array_r = \@array;
取雜湊的引用:my $hash_r = \%hash;
1、一般的標量Perl引用
sub add{ my($a,$b)[email protected]_; $$a++; $$b++; }
$a=1; $b=2;
add(\$a,\$b); print "$a,$b\n"; # 輸出:2,3。
說明:取變數的Perl引用可以用“\”符號,解Perl引用用“$”符號。
2、陣列的Perl引用
陣列的Perl引用和標量的Perl引用一樣,在陣列名前面加“\”,只是在解Perl引用的時候,使用@符號。如:
@abc=(1,2,3);
$ref = \@abc;
print “@$ref \n”; #輸出1,2,3。
print “@$ref[0] \n”; #輸出1。
3、對雜湊表的Perl引用
和陣列類似,但是當解Perl引用時要使用$符號,如:
%hash=(abc=>123, def=>456);
$ref=\%hash;
print "%$ref \n"; # 輸出:%HASH(0x83179b4)
print "$$ref{abc}\n"; # 輸出:123
引用的賦值
$aref2 = $aref1; 將使得$aref2和$aref1指向同一個陣列,如果想將$aref1指向的陣列拷貝一份給$aref2的話,使用下面的方法,[]裡面對陣列進行解引用,而[]以解引用後的陣列為內容生成了一個新的匿名陣列,又賦值給$aref2。
$aref2 = [@{$aref1}];
注意:不能使用下面的形式,外層的[]是不可缺少的。由於=左邊是標量,所以右邊的陣列會被解釋為標量環境,得到的是陣列元素個數,而不是元素本身。但是如果加上[]就可以了,這樣perl知道這是一個匿名陣列的賦值。
$aref2 = @{$aref1};
判斷一個變數是否是引用
my $aref1 = [1, 2, 0] ;
print ref $aref1, "\n" ; #輸出 ARRAY
if (ref $aref1) {
print "true\n" ; #輸出 true
}
判斷兩個引用是否指向同一個目標
my $aref1 = [1, 2, 0] ;
my $aref2 = $aref1 ;
print $aref1, "\n" ;
print $aref2, "\n" ;
if ($aref1 eq $aref2) {
print "reference equal\n" ;
}
if($aref1 == $aref2) {
print "reference equal\n" ;
}
例1:
sub getarrays{
my($fruit_ref,$veg_ref) = @_;
...
}
@fruit = qw(apples oranges banana);
@veggies = qw(carrot cabbage turnip);
getarrays(\@fruit, \@veggies);
例2:
sub func
{
my($a,$b,$c) = @_; # 這裡$b,$c接收到的是陣列的引用
print "$a\n";
my $count = 0;
while($count < @$b)
{
print "$b->[$count]\n";
$count++;
}
$count = 0;
while($count < @$c)
{
print "$c->[$count]\n";
$count++;
}
}
my @arry1 = ("fff", "rrr", "www");
my @arry2 = ("ttt", "hhh", "ccc");
func("qqq", \@arry1, \@arry2); # 這裡傳入陣列的引用
二維陣列
@a = {
(a,b,c,d,e)
(f,g,h,i,j,k)
(l,m,n,o,p)
(q,r,s,t,u)
(v,w,x,y,z)
}
從上述二維陣列的每一行的陣列中選出一個元素,列舉出所有的組合方式.
例如可行組合(a,f,l,q,v),(b,h,o,s,z)等。
my @A = ( [ 1 .. 4 ], [ 'A' .. 'C' ], [ 'a', 'b' ], [ 10 .. 13 ] );
sub Combine {
my @R = @{ +shift };# @R = [1..4]
for my $e (@_) {
@R = map { my $r = $_; map "$r $_", @$e } @R;#其中@$e是參考引用
}
return @R;
}
my @w = Combine @A;
foreach my $t (@w){
print $t."\n";
}
#say for @w