我有一些代码:
my %hosts = (
'USAmazon' => ['US','CA'],
'EUAmazon' => ['GB', 'FR', 'IT', 'ES', 'DE'],
'CNAmazon' => ['CN'],
'JPAmazon' => ['JP'],
);
my @values = $hosts{$ARGV[0]};
我看到$values[0][0]
持有美国,$values[0][1]
持有CA.为什么会这样?请解释一下。
另外,如何找出$values[0]
的长度?
scalar $values[0]
打印出类似ARRAY(0x12FFc)
blah..blah ......
任何链接也都有帮助。
答案 0 :(得分:5)
你是Perl中的新手,你已经点击引用 ......
在Perl中,有三种标准类型的数据:
$foo
。@foo
,将单个项称为$foo[1]
。%foo
,将单个项称为$foo{BAR}
。请注意,所有这些都包含单个值。数组或散列的每个元素只能有一个值。例如,我有一台主机(USAmazon
,EUAmazon
等),我希望每个主机与一个国家/地区相关联($host{USAmazon} = 'US';
,{{1} GB`等)。这很简单,很容易在Perl中实现。
不幸的是,事实并非如此。每台主机都可以与国家代码的整个阵列相关联。如何将整个可能的国家/地区代码放入主机的哈希? 这是引用的地方。想象一下,我有一个国家代码列表。如果我能找到该列表的内存位置,我可以将该内存位置用作哈希中的引用。因此,我的哈希包含每个键的单个值。只是关键是内存中特定列表的位置。
这就是引用的含义,以及为什么有时会看到$host{EUAmazon} =
之类的值。这恰好是存储在哈希中的某个数组的内存位置。
在引用上有一个很好的Perl tutorial,它实际上是标准Perl发行版的一部分。这是一个很好的起点。
快速基本指南,但是......
例如:
ARRAY(0x12FFc)
如果我打印$reference_to_foo_array = \@foo;
,我会收到类似$reference_to_foo_array
的内容,告诉我这是内存位置ARRAY(0x12FFc)
的数组。但是,我现在可以将整个数组0x12FFc
存储到单个散列或数组元素中:
@foo
例如:
$some_array[0] = $reference_to_foo_array;
在很多情况下,我可以消除花括号:
@another_array = @{$reference_to_foo_array};
我可以拥有非常复杂的物体。例如。我有一个哈希的人,每个哈希包含一个手机类型的哈希。每种电话类型都包含该类型的电话列表。例如,我可能有两个工作电话号码和两部手机:
@another_array = @$reference_to_foo_array;
这是指DAVID的手机。但是,这实际上是手机类型的哈希。如果我打印出来,我会得到类似 $person{DAVID};
的内容:
如果我想要特定的手机类型,我会这样做:
Hash(0x12b23)
这是David的手机号码列表。如果我打印这个,我会得到像 ${$person{DAVID}}{CELL};
这样的东西,因为它是一个电话号码数组的参考。
这是指DAVID的第一部手机:
Array(0x3458b)
没有括号,你会看到:
${${$phone{DAVID}}{CELL}}[0];
幸运的是,Perl的语法糖更容易阅读:
$$$phone{DAVID}{CELL}[0];
这表示有一个哈希(人)指的是另一个哈希(电话类型)引用一组电话号码。
Perl还有一种创建哈希或数组的方法,而无需实际命名。这会创建一个匿名哈希:
$phone{DAVID}->{CELL}->[0];
现在,我可以为DAVID提供一些手机类型。以下是我创建匿名数组的方法:
$phone{DAVID} = {};
现在,我可以获得DAVID的手机号码列表。
还有一些事情:
查看模块Data::Dumper。这有助于您打印出这些非常复杂的数据类型的结构,并帮助您了解您正在查看的内容。
查看Perl函数ref。这可以帮助你弄清楚你在看什么。例如:
我的$ data_type = ref $ phone {DAVID} - > {CELL}
会将$phone{DAVID}->{CELL} = [];
设置为$data_type
。这让我知道ARRAY
不是电话号码,而是电话号码列表(或者可能是其他参考类型的列表)。
答案 1 :(得分:3)
数组和哈希值始终是标量。在这种情况下,对于现有元素,$hosts{$ARGV[0]}
是包含对数组的引用的标量。您需要取消引用该引用以获取该数组。
my $length = @{ $hosts{$ARGV[0]} };
答案 2 :(得分:0)
%hosts
哈希将数组引用保存为值。
你只需要取消引用它们:
my @values = @{$hosts{$ARGV[0]}};
答案 3 :(得分:-1)
有关
my @values = $hosts{$ARGV[0]};
其中$ARGV[0]
是您的哈希的键之一,例如'USAmazon'
,%hosts
哈希中的相应值将为
['US','CA']
这是一个匿名数组引用。此结构[ LIST ]
用于创建要用作标量值的数组引用,例如:
my $foo = [ 1, 2, 3 ]; # $foo is a scalar
如果您要从现有阵列中进行此操作,您也可以这样做:
my @foo = (1, 2, 3); # @foo is an array
my $foo = \@foo; # reference to an array @foo
但是,这将生成指向数组的硬编码链接。使用匿名数组不会。
在散列(或数组)中,值只能是标量值。因此,如果将哈希值分配给数组,则将为数组中的第一个元素分配该标量值。数组的第一个元素当然是$array[0]
。所以:
my $foo = $hosts{$ARGV[0]}; # [ 'US', 'CA' ]
my @bar = $foo;
print $bar[0]; # prints the array reference ARRAY(...)
print $foo; # same thing
print $foo->[0]; # 'US'
print $bar[0][0]; # 'US' (same thing)
有关详细信息,请参阅perldoc perldata。