你在这里有一些困惑。如果sigil(var名称前面的符号)是$
,则表示有标量值。
以下是你需要记住的事情的清单:
- 两个
$hash
和$arr_ref
是引用,所以变量名有$
,因为他们只存储一个存储器地址引用到实际的散列/阵列是。
- 一个数组有一个
@
印记,并且一个散列有一个%
印记。所以@array
和%hash
都是而不是的引用。
- 如果你想在Perl中把数据结构放到另一个数据结构中,你需要引用它。这是通过将
\
放在变量名称前面来完成的,如$ref = \@array
。
- 数组获取分配列表:分配
my @colors = ('red', 'green');
- 散列得到的列表(括号用):
%count = ('red' => 5, 'green' => 2);
- 要访问的散列值,使用
$count{'red'}
。由于整个标识符count{'red'}
后面的值现在是标量值,因此sigil更改为$
。
- 要访问的数组值,则使用
$colors[0]
(这将给'red'
。
- 的
keys
函数返回的列表。
- 强制列表或数组成标量环境会给其元素的个数。
现在有了这些知识,你会看到,当你分配给keys($hash)
$arr_ref
,您强制标量上下文,因此你得到的计数。
- 如果您想要一个密钥数组,请使用
my @array = keys($hash)
。
- 如果你想要一个数组参考,使用
my $arr_ref = \keys($hash)
或将keys
返回的列表放入数组ref,如my $arr_ref = [ keys($hash) ]
。
另请注意,Perl的keys
built-in最近才学会处理引用。你应该给它一个哈希值,或像keys(%{ $hash_ref })
一样取消引用你的哈希引用。这可以缩短为keys %$hash_ref
。
此外,总是use strict
和use warnings
,因为这两者都会告诉你你做错了什么或者你可能会感到困惑的事情。
为了说明更多,我已将您的第一段代码重写为三种不同的形式。
没有引用:
use strict;
use warnings;
use Data::Dumper;
my %hash = (
1 => "asd",
21 => "fafafa"
);
my @array_of_keys =();
for my $key (keys %hash)
{
push @array_of_keys, $key;
}
print Dumper(\@array_of_keys); # reference the array because it looks nicer in Dumper
参考的数组:
use strict;
use warnings;
use Data::Dumper;
my %hash = (
1 => "asd",
21 => "fafafa"
);
my $arrayref_of_keys = [];
for my $key (keys %hash)
{
push @$arrayref_of_keys, $key; # or @{ $foo }
}
print Dumper($arrayref_of_keys); # it's already a ref, so no need for \
的所有引用:
use strict;
use warnings;
use Data::Dumper;
my %hashref = { # notice the curly braces instead of round parens
1 => "asd",
21 => "fafafa"
};
my $arrayref_of_keys = [];
for my $key (keys %$hashref) # or %{ $foo }
{
push @$arrayref_of_keys, $key; # or @{ $foo }
}
print Dumper($arrayref_of_keys);
我建议你阅读perlref和perlreftut。
您对Perl的变量类型的性质感到困惑。例如,'my $ hash = {};'这两行在你的例子中都没有任何用处。删除该行,它将没有区别。 Perl变量是最后分配给它的类型。因此,虽然'my $ arr_ref = [];'这一行使'$ arr_ref'成为此时数组的引用,'$ arr_ref = keys($ hash)'行为'keys()'提供了一个标量上下文,导致返回数组的长度。它需要是'@ $ arr_ref = keys($ hash)'来提供一个数组上下文。 – ooga