Perl 简明教程
Perl - References
Perl 引用是一种标量数据类型,它可以保存另一个值的地址,该值可以是标量、数组或哈希。由于其标量特质,引用可以像标量一样在任何地方使用。
您可以构造包含指向其他列表的引用的列表,其中可以包含指向哈希的引用,以此类推。这正是嵌套数据结构在 Perl 中构建的方式。
Create References
可以通过在变量、子例程或值之前加上反斜杠轻松创建引用,如下所示:
$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" };
Dereferencing
取消引用会返回从引用点指向该地址的值。要取消引用的引用,只需在引用变量前使用 $、@ 或 %,具体取决于引用指向的是标量、数组还是哈希。下面是说明此概念的示例:
#!/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
Circular References
当两个引用相互引用时,就会发生循环引用。创建引用时您必须小心,否则循环引用可能导致内存泄漏。下面就是一个示例:
#!/usr/bin/perl
my $foo = 100;
$foo = \$foo;
print "Value of foo is : ", $$foo, "\n";
當以上程式執行時,會產生以下結果 −
Value of foo is : REF(0x9aae38)
References to Functions
这种情况可能发生在您需要创建一个信号处理程序时,您可以通过在函数名前加上 & 来生成对函数的引用,并且只需使用 & 前缀引用变量即可取消引用该引用。下面就是一个示例:
#!/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