为什么空的Perl哈希有一个键?

时间:2011-04-12 09:48:27

标签: perl hash size key

标准的googleable回答“如何找出Perl中哈希的大小?”是“取keys(%hash)”的大小:

my %h = {};
print scalar (keys (%h));

这会打印'1'。我期待零。另一方面。类似地,

my %h = {};
$h{"a"} = "b";
$h{"x"} = "y";
print scalar keys (%h);
print "\nKey: $_" for (keys %h);

打印:

  

3

     

关键:a

     

键:x

     

键:HASH(0x229e8)

这个额外价值来自哪里?

4 个答案:

答案 0 :(得分:24)

$ perl -Mwarnings -e'my %h = {}'
Reference found where even-sized list expected at -e line 1.
出于很好的理由,

strictwarnings包含在Perl中。没有理由不使用它们。

更好的是,将diagnostics添加到混音中:

$ perl -Mwarnings -Mdiagnostics -e'my %h = {}'
Reference found where even-sized list expected at -e line 1 (#1)
    (W misc) You gave a single reference where Perl was expecting a list
    with an even number of elements (for assignment to a hash). This usually
    means that you used the anon hash constructor when you meant to use
    parens. In any case, a hash requires key/value pairs.

        %hash = { one => 1, two => 2, };    # WRONG
        %hash = [ qw/ an anon array / ];    # WRONG
        %hash = ( one => 1, two => 2, );    # right
        %hash = qw( one 1 two 2 );      # also fine

答案 1 :(得分:21)

这也让我感到很沮丧。

my %h = ();

请注意使用()代替{}

说明:值{}是哈希的引用,而不是哈希本身。在Perl中,引用是一种标量值,对%h的赋值具有分配单个标量值的特殊处理。它将标量字符串化(在您的情况下为您提供字符串HASH(0x229e8)),并将该键与值undef相关联。

使用()时,从列表到散列的分配会从列表中的对创建键/值对,并且由于()为空,散列%h变为空。

答案 2 :(得分:7)

{}是对匿名哈希的引用。因此my %h = {}相当于我的%h = ({} => undef)

Perl要求散列键是字符串,因此当您使用引用作为键时,Perl使用引用的字符串表示形式(HASH(0x229e8))。

答案 3 :(得分:6)

use Data::Dumper;

my %h = {};
warn Dumper \%h;

%h被分配了一个哈希引用作为键,undef作为值。

输出:

$VAR1 = {
          'HASH(0x8683830)' => undef
        };

正如rafl建议的那样,warnings pragma会抓住这个。 请查看Greg Hewgillanswer以获取更正后的代码。