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

spr*_*aff 8 size perl hash key

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

my %h = {};
print scalar (keys (%h));
Run Code Online (Sandbox Code Playgroud)

这打印'1'.我期待零.另一方面.同样的,

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

打印:

3

关键:a

关键:x

密钥:HASH(0x229e8)

这个额外价值来自哪里?

Dav*_*oss 24

$ perl -Mwarnings -e'my %h = {}'
Reference found where even-sized list expected at -e line 1.
Run Code Online (Sandbox Code Playgroud)

Perl中包含严格警告,原因非常充分.没有理由不使用它们.

更好的是,还要在混合中添加诊断功能:

$ 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
Run Code Online (Sandbox Code Playgroud)

  • 'diagnostics'仅用于调试.程序投入生产时将其删除. (7认同)
  • 使用`splain`命令行实用程序来解释perl错误消息. (3认同)

Gre*_*ill 21

这也让我有点咬我.

my %h = ();
Run Code Online (Sandbox Code Playgroud)

注意使用()而不是{}.

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

使用时(),从列表到散列的赋值从列表中的对创建键/值对,并且由于()是空的,所以散列%h变为空.

  • 关于被咬,没有理由用`=();`来声明.`my%h;`打字少,容易出错. (6认同)
  • 分配单元素列表绝不是特别的; 这种说法使整体答案具有误导性. (3认同)

Eug*_*ash 7

{}是对匿名哈希的引用.所以my %h = {}相当于我的%h = ({} => undef).

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


Ala*_*avi 6

use Data::Dumper;

my %h = {};
warn Dumper \%h;
Run Code Online (Sandbox Code Playgroud)

%h获得一个哈希引用作为键和undef值.

输出:

$VAR1 = {
          'HASH(0x8683830)' => undef
        };
Run Code Online (Sandbox Code Playgroud)

正如rafl所说的那样,实用主义warnings会抓住这个.看看Greg Hewgill对纠正码的回答.