1

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

为什么?

4

2 回答 2

3

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

在 Perl 5 中,sigil 表示——在非技术意义上——你的表达式的上下文。除了切片在标量上下文中的一些非标准行为外,基本思想是 sigil 表示您想从表达式中得到什么。

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

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

为您提供哈希中的项目列表。和,

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

为您提供数组中的前四个项目。--> 对于您的情况,@list[2]仍然有一个索引“列表”,只是该列表是“一个列表”的特例。

由于标量和列表上下文定义得相当好,并且没有“散列上下文”,它在$标量和@“列表”中保持相当稳定,直到最近,Perl 不支持使用%. 所以既没有%hash{@keys}%hash{key}没有意义。但是,现在,您可以通过将%印记放在前面来转储具有值的索引对。

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,你可以。


但是为了一个完整主义者的缘故,切片有一种非直观的方式,它们在标量环境中工作。因为将列表放入标量上下文的标准行为是对列表进行计数,如果切片与该行为一起使用:

( $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] }

但只是轻微的。

于 2015-02-26T03:29:17.500 回答
1

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

另一方面,%dict{1}可以工作,但不会在双引号内插值。因此,类似的东西my %partial_dict = %dict{1,3}是有效的,并且会按照您的期望进行,即%partial_dict现在将具有 value (1,2,3,4)。但是"%dict{1,3}"(在引号中)仍将打印为%dict{1,3}.

Perl Cookbook有一些关于打印散列的技巧。

于 2015-02-26T03:14:10.367 回答