为什么我可以使用@list 来调用数组,但不能使用%dict 来调用perl 中的散列?
Why I can use @list to call an array, but can't use %dict to call a hash in perl?
今天开始我的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
对array和hash都有效,但是@ + var_name
可以用来调用array,同时% + var_name
不能用来调用hash。
为什么?
数组在双引号内插入,因此您会看到打印的数组的实际内容。
另一方面,%dict{1}
有效,但未插入双引号内。因此,my %partial_dict = %dict{1,3}
之类的东西是有效的,并且符合您的预期,即 %partial_dict
现在将具有值 (1,2,3,4)
。但是 "%dict{1,3}"
(在引号中)仍将打印为 %dict{1,3}
.
Perl Cookbook 有一些关于打印哈希值的技巧。
@list[2]
有效,因为它是列表的 切片 。
在 Perl 5 中,印记表示——在非技术意义上——你的表达式的 上下文。除了切片在标量上下文中的一些非标准行为外,基本思想是印记代表您想要 得到 表达式的内容。
如果您想要散列中的标量,它是 $hash{key}
。
如果你想要一个数组中的标量,它是 $array[0]
。 但是,Perl 允许您获得聚合的片。这允许您在一个紧凑的表达式中检索多个值。切片采用 list 索引。所以,
@list = @hash{ qw<key1 key2> };
为您提供散列中的项目列表。而且,
@list2 = @list[0..3];
为您提供数组中的前四项。 --> 对于您的情况,@list[2]
仍然有一个 "list" 索引,只是该列表是 "list of one" 的特例。
由于标量和列表上下文定义得相当好,并且没有 "hash context",它在标量 $
和 "lists" 保持在 @
并且直到最近,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,则可以。
但出于完美主义者的考虑,切片在标量环境中的工作方式并不直观。因为将列表放入标量上下文的标准行为是 count 列表,如果切片适用于该行为:
( $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] }
但只是轻微的。
今天开始我的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
对array和hash都有效,但是@ + var_name
可以用来调用array,同时% + var_name
不能用来调用hash。
为什么?
数组在双引号内插入,因此您会看到打印的数组的实际内容。
另一方面,%dict{1}
有效,但未插入双引号内。因此,my %partial_dict = %dict{1,3}
之类的东西是有效的,并且符合您的预期,即 %partial_dict
现在将具有值 (1,2,3,4)
。但是 "%dict{1,3}"
(在引号中)仍将打印为 %dict{1,3}
.
Perl Cookbook 有一些关于打印哈希值的技巧。
@list[2]
有效,因为它是列表的 切片 。
在 Perl 5 中,印记表示——在非技术意义上——你的表达式的 上下文。除了切片在标量上下文中的一些非标准行为外,基本思想是印记代表您想要 得到 表达式的内容。
如果您想要散列中的标量,它是 $hash{key}
。
如果你想要一个数组中的标量,它是 $array[0]
。 但是,Perl 允许您获得聚合的片。这允许您在一个紧凑的表达式中检索多个值。切片采用 list 索引。所以,
@list = @hash{ qw<key1 key2> };
为您提供散列中的项目列表。而且,
@list2 = @list[0..3];
为您提供数组中的前四项。 --> 对于您的情况,@list[2]
仍然有一个 "list" 索引,只是该列表是 "list of one" 的特例。
由于标量和列表上下文定义得相当好,并且没有 "hash context",它在标量 $
和 "lists" 保持在 @
并且直到最近,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,则可以。
但出于完美主义者的考虑,切片在标量环境中的工作方式并不直观。因为将列表放入标量上下文的标准行为是 count 列表,如果切片适用于该行为:
( $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] }
但只是轻微的。