在perl中,可以使用哈希,例如我的%a =(2,“两个”);以及hashrefs,例如我的$b = {2 => “二”};
每当我创建一个多维哈希时,顶级哈希的值总是hashrefs,即在它们上调用ref()会返回“HASH”.是否有可能只有哈希的散列,没有额外的间接水平?
另外,当使用哈希散列时,perl允许在访问子哈希的元素时省略解除引用运算符:
my %a; $a{2} = {2 => "two"}; # the following are both valid: $a{2}->{2} $a{2}{2}
我假设第二个只是第一个语法糖.但是,这似乎与简单的非嵌套hashref所需的语法不一致,因为$b-> {2}有效,而$b {2}则不然.
我问的理由是我想说的
for my %hash (values %a) {
甚至
for my %hash (map(%{$_},values %a)) {
但是这两个都会在编译时导致“丢失$on循环变量”错误.
解决方法
一开始,只有标量,散列和数组.实际上,这就是Perl4,但是在设计Perl5时,绝对向后兼容性是一个关键点.这意味着$hash {entry} = @array必须继续将数组大小分配给该哈希条目,而不是将数组放入哈希.因此集合只能包含标量.
这是需要引用的主要原因之一 – 哈希引用和数组引用允许我们将集合称为单个标量事物.哈希引用的语法需要与哈希的语法不同.解除引用箭头 – > (从C借用)可用于hashref访问:$hashref-> {entry}.因为哈希永远不能直接包含集合,所以下标之间的取消引用箭头对于消除散列和hashref之间的消歧是不必要的,所以$ref-> {a} – > {b}和$ref-> {a} {b}做同样的事.但是,hashref访问不能使用$ref {entry},因为该语法已经用于散列访问,因为$name和%name可以作为单独的变量同时存在.
简而言之,语法很难看,但出于向后兼容的原因.
目前,据我所知,我的%hash(@hash_references)或我的@array(@hash_references)是不允许的.我个人认为这种语法没有任何问题,但隐式解除引用无疑是相当混乱的.必须使用%$ref而不是%hash并不是那么糟糕.
顺便说一句,Perl6摆脱了引用,因为除了向后兼容性之外,哈希和hashref之间的这种差异是非常不必要的.集合变量的行为更像是标量,尽管有一些新的上下文如“项目上下文”来帮助缺少引用.