Perl 简明教程

Perl - References

Perl 引用是一种标量数据类型,它可以保存另一个值的地址,该值可以是标量、数组或哈希。由于其标量特质,引用可以像标量一样在任何地方使用。

A Perl reference is a scalar data type that holds the location of another value which could be scalar, arrays, or hashes. Because of its scalar nature, a reference can be used anywhere, a scalar can be used.

您可以构造包含指向其他列表的引用的列表,其中可以包含指向哈希的引用,以此类推。这正是嵌套数据结构在 Perl 中构建的方式。

You can construct lists containing references to other lists, which can contain references to hashes, and so on. This is how the nested data structures are built in Perl.

Create References

可以通过在变量、子例程或值之前加上反斜杠轻松创建引用,如下所示:

It is easy to create a reference for any variable, subroutine or value by prefixing it with a backslash as follows −

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

您无法使用反斜杠运算符在 I/O 句柄(文件句柄或目录句柄)上创建引用,但是可以使用方括号创建一个指向匿名数组的引用,如下所示:

You cannot create a reference on an I/O handle (filehandle or dirhandle) using the backslash operator but a reference to an anonymous array can be created using the square brackets as follows −

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

类似地,您可以使用花括号创建一个指向匿名哈希的引用,如下所示:

Similar way you can create a reference to an anonymous hash using the curly brackets as follows −

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

可以通过在不带子例程名的情况下使用 sub 创建对匿名子例程的引用,如下所示:

A reference to an anonymous subroutine can be created by using sub without a subname as follows −

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

Dereferencing

取消引用会返回从引用点指向该地址的值。要取消引用的引用,只需在引用变量前使用 $、@ 或 %,具体取决于引用指向的是标量、数组还是哈希。下面是说明此概念的示例:

Dereferencing returns the value from a reference point to the location. To dereference a reference simply use $, @ or % as prefix of the reference variable depending on whether the reference is pointing to a scalar, array, or hash. Following is the example to explain the concept −

#!/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";

當以上程式執行時,會產生以下結果 −

When above program is executed, it produces the following result −

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

如果您不确定变量的类型,可以使用 ref 轻松了解它的类型,如果它的参数是引用,它将返回以下字符串之一。否则,它将返回 false:

If you are not sure about a variable type, then its easy to know its type using ref, which returns one of the following strings if its argument is a reference. Otherwise, it returns false −

SCALAR
ARRAY
HASH
CODE
GLOB
REF

让我们尝试以下示例:

Let’s try the following example −

#!/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";

當以上程式執行時,會產生以下結果 −

When above program is executed, it produces the following result −

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

Circular References

当两个引用相互引用时,就会发生循环引用。创建引用时您必须小心,否则循环引用可能导致内存泄漏。下面就是一个示例:

A circular reference occurs when two references contain a reference to each other. You have to be careful while creating references otherwise a circular reference can lead to memory leaks. Following is an example −

#!/usr/bin/perl

 my $foo = 100;
 $foo = \$foo;

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

當以上程式執行時,會產生以下結果 −

When above program is executed, it produces the following result −

Value of foo is : REF(0x9aae38)

References to Functions

这种情况可能发生在您需要创建一个信号处理程序时,您可以通过在函数名前加上 & 来生成对函数的引用,并且只需使用 & 前缀引用变量即可取消引用该引用。下面就是一个示例:

This might happen if you need to create a signal handler so you can produce a reference to a function by preceding that function name with \& and to dereference that reference you simply need to prefix reference variable using ampersand &. Following is an example −

#!/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);

當以上程式執行時,會產生以下結果 −

When above program is executed, it produces the following result −

Item : name
Item : Tom
Item : age
Item : 19