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

为什么我可以使用@list调用数组,但不能在perl中使用%dict调用哈希?,perl,sigils,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对数组和哈希都有效,但是@+

今天我开始我的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不能用来调用哈希


为什么?

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

另一方面,%dict{1}起作用,但不在双引号内插值。因此,像我的%partial_dict=%dict{1,3}这样的东西是有效的,并且做了您所期望的事情,即%partial_dict现在的值为1,2,3,4。但是引号中的%dict{1,3}仍将打印为%dict{1,3}


有一些打印哈希的技巧。

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

另一方面,%dict{1}起作用,但不在双引号内插值。因此,像我的%partial_dict=%dict{1,3}这样的东西是有效的,并且做了您所期望的事情,即%partial_dict现在的值为1,2,3,4。但是引号中的%dict{1,3}仍将打印为%dict{1,3}

有一些打印哈希的技巧。

@list[2]之所以有效,是因为它是列表的一部分

在Perl 5中,符号从非技术意义上表示表达式的上下文。除了在标量上下文中切片具有的一些非标准行为之外,基本思想是sigil表示您希望从表达式中获得的内容

如果要从散列中提取标量,它是$hash{key}。 如果要从数组中提取标量,则为$array[0]。然而,Perl允许您获取聚合的切片。这允许您在紧凑表达式中检索多个值。切片获取索引列表。所以

@list = @hash{ qw<key1 key2> };
提供数组中的前四项。->对于您的情况,@list[2]仍然有一个索引列表,只是该列表是一个索引列表的特例

由于标量和列表上下文定义得相当好,并且没有散列上下文,所以标量和列表的值分别保持在$for标量和@for列表,直到最近,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' )
这将使表达:

$item = @hash{ @keys };
$s = ( $hash{$keys[0]}, $hash{$keys[1]}, ... , $hash{$keys[$#keys]} );
价值不超过:

scalar @keys;
$item = $hash{ $keys[-1] };
因此,Perl似乎将其视为表达式:

$item = @hash{ @keys };
$s = ( $hash{$keys[0]}, $hash{$keys[1]}, ... , $hash{$keys[$#keys]} );
当在标量上下文中计算逗号分隔的列表时,它会指定最后一个表达式。所以它真的结束了

$item = @hash{ @keys }; 
其价值不超过:

scalar @keys;
$item = $hash{ $keys[-1] };
但它让写作变得像这样:

$item = $hash{ source1(), source2(), @array3, $banana, ( map { "$_" } source4()};
比写作稍微容易一些:

$item = $hash{ [source1(), source2(), @array3, $banana, ( map { "$_" } source4()]->[-1] }
但这只是一点点。

@list[2]起作用,因为它是列表的一部分

在Perl 5中,符号从非技术意义上表示表达式的上下文。除了在标量上下文中切片具有的一些非标准行为之外,基本思想是sigil表示您希望从表达式中获得的内容

如果要从散列中提取标量,它是$hash{key}。 如果要从数组中提取标量,则为$array[0]。然而,Perl允许您获取聚合的切片。这允许您在紧凑表达式中检索多个值。切片获取索引列表。所以

@list = @hash{ qw<key1 key2> };
提供数组中的前四项。->对于您的情况,@list[2]仍然有一个索引列表,只是该列表是一个索引列表的特例

由于标量和列表上下文定义得相当好,并且没有散列上下文,所以标量和列表的值分别保持在$for标量和@for列表,直到最近,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' )
这将使表达:

$item = @hash{ @keys };
$s = ( $hash{$keys[0]}, $hash{$keys[1]}, ... , $hash{$keys[$#keys]} );
价值不超过:

scalar @keys;
$item = $hash{ $keys[-1] };
因此,Perl似乎将其视为表达式:

$item = @hash{ @keys };
$s = ( $hash{$keys[0]}, $hash{$keys[1]}, ... , $hash{$keys[$#keys]} );
当在标量上下文中计算逗号分隔的列表时,它会指定最后一个表达式。所以它真的结束了

$item = @hash{ @keys }; 
其价值不超过:

scalar @keys;
$item = $hash{ $keys[-1] };
但它让写作变得像这样:

$item = $hash{ source1(), source2(), @array3, $banana, ( map { "$_" } source4()};
比写作稍微容易一些:

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

但仅为轻微。

启用警告时,%dict=1,2,3,4,5;将对奇数个元素发出警告。@list[2]也应发出警告。启用警告后,%dict=1,2,3,4,5;将对奇数个元素发出警告。@list[2]也应该发出警告。实际上,它们的含义是-perl-e“%h=a=>1,b=>2;打印联接,%h{a,b}打印一个1b2。不过,我不确定这是否是perl最近添加的内容—我正在使用perl 5.20来运行它。@skmrx,这实际上是有道理的,现在您提到了,我听说类似的东西正在开发中。我很高兴他们做出了改变。我可以扔掉我的哈希子集库。我得改一下课文。我想知道%array[0,
2] 在Perl5中,sigil表示表达式的上下文是错误的。表达式本身不能有上下文。例如,如果我写$last=@arr[2],那么它是在标量上下文中;打印联接,%h{a,b}打印一个1b2。不过,我不确定这是否是perl最近添加的内容—我正在使用perl 5.20来运行它。@skmrx,这实际上是有道理的,现在您提到了,我听说类似的东西正在开发中。我很高兴他们做出了改变。我可以扔掉我的哈希子集库。我得改一下课文。我想知道%array[0,2]是否也会抛出索引。在Perl 5中,一个符号表示表达式的上下文是错误的。表达式本身不能有上下文。例如,如果我写$last=@arr[2],那么它是在标量上下文中。