Perl - 引用



Perl 引用是一種標量資料型別,它儲存另一個值的地址,該值可以是標量、陣列或雜湊表。由於其標量特性,引用可以在任何可以使用標量的地方使用。

您可以構造包含對其他列表的引用的列表,這些列表可以包含對雜湊表的引用,依此類推。這就是 Perl 中巢狀資料結構的構建方式。

建立引用

為任何變數、子程式或值建立引用很容易,只需在其前面加上反斜槓即可,如下所示:

$scalarref = \$foo;
$arrayref  = \@ARGV;
$hashref   = \%ENV;
$coderef   = \&handler;
$globref   = \*foo;

您不能使用反斜槓運算子建立 I/O 控制代碼(檔案控制代碼或目錄控制代碼)的引用,但可以使用方括號建立對匿名陣列的引用,如下所示:

 $arrayref = [1, 2, ['a', 'b', 'c']];

類似地,您可以使用花括號建立對匿名雜湊表的引用,如下所示:

$hashref = {
   'Adam'  => 'Eve',
   'Clyde' => 'Bonnie',
};

可以使用不帶子程式名的 `sub` 建立對匿名子程式的引用,如下所示:

$coderef = sub { print "Boink!\n" };

解引用

解引用從引用指向的位置返回該值。要解引用,只需根據引用指向標量、陣列或雜湊表,在引用變數前面使用 $、@ 或 % 即可。以下示例解釋了該概念:

#!/usr/bin/perl

$var = 10;

# Now $r has reference to $var scalar.
$r = \$var;

# Print value available at the location stored in $r.
print "Value of $var is : ", $$r, "\n";

@var = (1, 2, 3);
# Now $r has reference to @var array.
$r = \@var;
# Print values available at the location stored in $r.
print "Value of @var is : ",  @$r, "\n";

%var = ('key1' => 10, 'key2' => 20);
# Now $r has reference to %var hash.
$r = \%var;
# Print values available at the location stored in $r.
print "Value of %var is : ", %$r, "\n";

執行上述程式後,會產生以下結果:

Value of 10 is : 10
Value of 1 2 3 is : 123
Value of %var is : key220key110

如果您不確定變數型別,則可以使用 **ref** 很容易地知道其型別,如果其引數是引用,則返回以下字串之一。否則,返回 false:

SCALAR
ARRAY
HASH
CODE
GLOB
REF

讓我們嘗試以下示例:

#!/usr/bin/perl

$var = 10;
$r = \$var;
print "Reference type in r : ", ref($r), "\n";

@var = (1, 2, 3);
$r = \@var;
print "Reference type in r : ", ref($r), "\n";

%var = ('key1' => 10, 'key2' => 20);
$r = \%var;
print "Reference type in r : ", ref($r), "\n";

執行上述程式後,會產生以下結果:

Reference type in r : SCALAR
Reference type in r : ARRAY
Reference type in r : HASH

迴圈引用

當兩個引用相互包含對方的引用時,就會發生迴圈引用。建立引用時必須小心,否則迴圈引用可能導致記憶體洩漏。以下是一個示例:

#!/usr/bin/perl

 my $foo = 100;
 $foo = \$foo;
 
 print "Value of foo is : ", $$foo, "\n";

執行上述程式後,會產生以下結果:

Value of foo is : REF(0x9aae38)

對函式的引用

如果您需要建立訊號處理程式,則可能會發生這種情況,您可以透過在函式名前面加上 `\&` 來生成對函式的引用,並且要解引用該引用,您只需使用 `&` 字首引用變數即可。以下是一個示例:

#!/usr/bin/perl

# Function definition
sub PrintHash {
   my (%hash) = @_;
   
   foreach $item (%hash) {
      print "Item : $item\n";
   }
}
%hash = ('name' => 'Tom', 'age' => 19);

# Create a reference to above function.
$cref = \&PrintHash;

# Function call using reference.
&$cref(%hash);

執行上述程式後,會產生以下結果:

Item : name
Item : Tom
Item : age
Item : 19
廣告