6

我可以直接访问列表中的元素:

$foo = (qw(a b c))[2]; # $foo = "c"

我可以将列表分配给哈希:

%h = (a=>0, b=>1, c=>2);
$foo = $h{c}; # $foo = 2

那么,为什么我不能直接将列表视为哈希?

$foo = (a=>0, b=>1, c=>2){c}; # Syntax error

我能找到的最接近的是创建一个 hashref:

$foo = {a=>0, b=>1, c=>2}->{c};

是否有正确的语法可以将列表作为散列访问,或者为什么不呢?

4

2 回答 2

6

您不能将列表用作散列,因为列表不是散列。:)

( =>"fat comma") 运算符与 相同,,但附加的功能是在左侧引用裸词。所以当你写这个时:

( a=>0, b=>1, c=>2 )

它与此完全相同:

( 'a', 0, 'b', 1, 'c', 2 )

这不是一个哈希,它只是一个列表。

列表是存在于堆栈中的短暂事物;正如您正确指出的那样,它们可以分配给数组和散列,但它们与数组和散列不同。

在使用之前需要构造一个哈希。分配给它的任何键/值列表都需要对键进行散列处理,分配桶并将值放置在桶中。所以当你写:

$foo = {a=>0, b=>1, c=>2}->{c};

正在发生的事情是:

  1. 列表中的元素 ( 'a', 0, 'b', 1, 'c', 2 ) 被放入堆栈
  2. 匿名哈希由{ LIST }操作员构造
  3. 列表元素从堆栈中弹出并分配给哈希,将它们变成键和值
  4. 返回对该哈希的引用。
  5. 引用由->操作员取消引用
  6. c查找密钥,然后
  7. 它的值返回,将表达式简化为$foo = 2

(qw(a b c))[2]那么,如果列表不是数组,为什么还要写呢?好吧,在内部,堆栈只是一个SV *'s 数组,所以我想将下标功能放在它上面很简单,而且似乎是个好主意。

这是一个非常酷的人写的一篇文章,你可能也会觉得很有启发性:Perl 中的数组与列表:有什么区别?

于 2013-09-19T21:12:18.447 回答
0

不,因为列表不是散列。你能做的最接近的是

my $foo = (a=>0,b=>1,c=>2)[5]; 
printf("$foo\n");

这将打印

2

因为上面的代码与

my $foo = ('a',0,'b',1,'c',2)[5]; 
printf("$foo\n");
于 2013-09-19T21:23:31.903 回答