为什么我可以使用@list来调用数组,但是不能使用%dict在perl中调用哈希?

时间:2015-02-26 02:56:30

标签: perl sigils

今天我开始了我的perl之旅,现在我正在探索数据类型。

我的代码如下:

@list=(1,2,3,4,5);
%dict=(1,2,3,4,5);

print "$list[0]\n";         # using [ ] to wrap index
print "$dict{1}\n";         # using { } to wrap key

print "@list[2]\n";
print "%dict{2}\n";

似乎$ + var_name适用于数组和散列,但@ + var_name可用于调用数组,同时% + var_name无法用于调用散列。< / p>

为什么?

2 个答案:

答案 0 :(得分:3)

@list[2]有效,因为它是列表的切片

在Perl 5中,sigil表示 - 在非技术意义上 - 表达式的 context 。除了切片在标量上下文中的一些非标准行为之外,基本思想是sigil代表你想要走出表达式的内容。

如果你想要一个哈希标量,那就是$hash{key}。 如果你想要一个数组中的标量,它就是$array[0]然而,Perl允许您获取聚合的切片。这允许您在紧凑表达式中检索多个值。切片采用列表索引。所以,

@list = @hash{ qw<key1 key2> };

为您提供散列中的项目列表。而且,

@list2 = @list[0..3];

为您提供数组中的前四项。 - &GT;对于您的情况,@list[2]仍然有一个&#34;列表&#34;索引,它只是一个&#34;列表中的一个&#34;的特殊情况。

由于标量和列表上下文定义相当明确,并且没有&#34;哈希上下文&#34;,它在$处于标量和@处于&#34;时保持稳定。列表&#34;直到最近,Perl不支持使用%寻址任何变量。因此,%hash{@keys}%hash{key}都没有意义。但是,现在,您可以通过将% sigil放在前面来转储带有值的索引对。

my %hash = qw<a 1 b 2>;
my @list = %hash{ qw<a b> }; # yields ( 'a', 1, 'b', 2 )
my @l2   = %list[0..2];      # yields ( 0, 'a', 1, '1', 2, 'b' )

所以,我想,如果你有一个旧版本的Perl,你就可以了,但如果你有5.20,你可以。


但是对于completist来说,切片有一种非直观的方式,它们在标量上下文中工作。因为将列表放入标量上下文的标准行为是计算列表,如果切片使用该行为:

( $item = @hash{ @keys } ) == scalar @keys;

哪个会表达:

$item = @hash{ @keys };

没有比以下更有价值了:

scalar @keys;

因此,Perl似乎将其视为表达式:

$s = ( $hash{$keys[0]}, $hash{$keys[1]}, ... , $hash{$keys[$#keys]} );

当在标量上下文中评估以逗号分隔的列表时,它会分配最后一个表达式。所以它真的结束了

$item = @hash{ @keys }; 

没有比以下更有价值了:

$item = $hash{ $keys[-1] };

但是它会写出这样的东西:

$item = $hash{ source1(), source2(), @array3, $banana, ( map { "$_" } source4()};

比写作容易:

$item = $hash{ [source1(), source2(), @array3, $banana, ( map { "$_" } source4()]->[-1] }

但只是轻微。

答案 1 :(得分:1)

数组在双引号内插,因此您可以看到打印数组的实际内容。

另一方面,%dict{1}有效,但未在双引号内插值。因此,my %partial_dict = %dict{1,3}之类的内容有效并且符合您的预期,即%partial_dict现在将具有值(1,2,3,4)。但"%dict{1,3}"(在引号中)仍将打印为%dict{1,3}

Perl Cookbook有一些关于打印哈希的提示。