我想在表达式中使用哈希。没问题:
use strict;
use warnings;
my %h = (a=>1, b=>2);
my $h = $h{a};
print "h='$h'\n";
但是因为我只提到它一次,所以我不想给它起名字。天真地用哈希内容代替$ h并不起作用。以下代码在"){":
的第3行产生语法错误use strict;
use warnings;
my $x = (a=>1, b=>2){a};
print "x='$x'\n";
我知道以下是实现我需要的方法:
use struct;
use warnings;
my $y = {a=>1, b=>2}->{a};
print "y='$y'\n";
为什么第二个例子不起作用?
编辑1:这是一个MVCE。在现实生活中,我的哈希键(在此示例中为' a)不是常量。
编辑2:关于我的动机更多一点:我不希望在我的代码中有一个不必要的变量范围,所以如果我要将%h的范围限制在它真正属于的范围,我会有这个:
use strict;
use warnings;
my $h;
{
my %h = (a=>1, b=>2);
$h = $h{a};
}
print "h='$h'\n";
我不想让%h留在范围内以获得比我需要的代码更多的代码,但是使用额外的块进行范围编写代码段也很笨拙。这就是为什么我正在寻找一种干净的单行方式进行分配。
答案 0 :(得分:5)
在my $x = (a=>1, b=>2){a};
中,这不代表哈希。这是一个包含以下值的列表:'a', 1, 'b', 2
。 =>
,又名胖子逗号只是一个美化的逗号,其功能是引用左侧的值。它并不暗示我们正在处理/创建哈希。例如:
my @array = ('a' => 1 => 'b' => 2);
要从显示的原始代码中获取值1
,您必须执行my $x = (a=>1, b=>2)[1];
。
您使用的hashref方法:my $y = {a=>1, b=>2}->{a};
是使用匿名哈希的标准方法。
答案 1 :(得分:3)
请参阅,(something1, something2, ...)
不是数组构造函数。这只是一种说法解释“我们在列表上下文中有所作为”的方式。您可以理解每个(a,b,c,...)
用法,例如对没有名称的数组的赋值。所以,是的,我们可以通过索引从这个数组中获取一个值。 ('a' => 1, 'b' => 2)[1]
将返回1
。
如果左侧是哈希变量,则只有在列表上下文中赋值后才会创建哈希值。在赋值之前,我们不能像hash那样使用这个列表,因为我们没有hash。因此不允许使用postcircumfix操作{...}
。