你有两个问题。我将分别回答它们:
问:在@{}
做什么?
当您编写 时@{$thing}
,您将取消对数组的引用。 $thing
正如您所注意到的,这只适用$thing
于数组引用。(其他解引用运算符%{$thing}
用于散列引用和${$thing}
标量引用。)
您确实需要一个取消引用运算符。考虑一下:
my $arrayref = [ 'Alice', 'Bob', 'Charlie' ];
my $hashref = { x => 4, y => 5 };
my $string = "Hello, world";
for my $thing ($arrayref, $hashref, $string) {
print "thing --> ", $thing, "\n";
print "scalar(thing) --> ", scalar($thing), "\n";
}
输出:
thing --> ARRAY(0x7f3b8054e468)
scalar(thing) --> ARRAY(0x7f3b8054e468)
thing --> HASH(0x7f3b80560678)
scalar(thing) --> HASH(0x7f3b80560678)
thing --> Hello, world
scalar(thing) --> Hello, world
$thing
强制使用标量上下文是没有意义的。它已经是一个标量了!
问题:如何安全地取消引用标量?
如果您不知道 中包含什么样的引用$thing
,您可以使用Ref::Util
它来检查它:
use Ref::Util qw( is_arrayref is_hashref );
for my $thing ($arrayref, $hashref, $string) {
if (is_arrayref($thing)) {
print "array: thing --> ", @{$thing}, "\n";
print "array: scalar(thing) --> ", scalar(@{$thing}), "\n";
}
elsif (is_hashref($thing)) {
print "hash: thing --> ", %{$thing}, "\n";
print "hash: scalar(thing) --> ", scalar(%{$thing}), "\n";
}
else
{
print "else: thing --> ", $thing, "\n";
}
}
输出:
array: thing --> AliceBobCharlie
array: scalar(thing) --> 3
hash: thing --> y5x4
hash: scalar(thing) --> 2/8
else: thing --> Hello, world
观察:
- 取消引用时,arrayref 成为其元素的列表。
print
输出没有分隔符的每个元素:AliceBobCharlie
- 当解除引用并强制转换为标量时,arrayref 变为元素的数量:
3
- hashref 被取消引用时,成为键和值的列表。
print
输出没有分隔符的每一对:y5x4
- hashref,当取消引用并强制转换为标量时,变成一个字符串,其中第一个数字是键的数量,第二个数字是哈希表中的桶数:
2/8