为什么一个空的 Perl 散列只有一个键?

发布于 2024-10-31 18:06:26 字数 417 浏览 0 评论 0原文

“如何找出 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

密钥:哈希(0x229e8)

这个额外的值从哪里来?

The standard googleable answer to "How do I find out the size of a hash in Perl?" is "take the size of keys(%hash)":

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

This prints '1'. I was expecting zero. On the other hand. Similarly,

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

Prints:

3

Key: a

Key: x

Key: HASH(0x229e8)

Where has this extra value come from?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

单挑你×的.吻 2024-11-07 18:06:26
$ perl -Mwarnings -e'my %h = {}'
Reference found where even-sized list expected at -e line 1.

严格

更好的是,也将 诊断 添加到组合中:

$ 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
$ perl -Mwarnings -e'my %h = {}'
Reference found where even-sized list expected at -e line 1.

strict and warnings are included with Perl for very good reasons. There is no reason not to use them.

Even better, add diagnostics into the mix too:

$ 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
め七分饶幸 2024-11-07 18:06:26

这也曾困扰过我。

my %h = ();

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

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

使用 () 时,从列表到哈希的赋值会根据列表中的对创建键/值对,并且由于 () 为空,因此哈希 %h 变为空。

This has bit me before too.

my %h = ();

Note the use of () instead of {}.

Explanation: The value {} is a reference to a hash, rather than a hash itself. In Perl, a reference is a kind of scalar value, and the assignment to %h has special processing for assigning a single scalar value. It stringifies the scalar (giving you the string HASH(0x229e8) in your case), and associates that key with the value undef.

When using (), the assignment from list to hash creates key/value pairs from pairs in the list, and since () is empty, the hash %h becomes empty.

oО清风挽发oО 2024-11-07 18:06:26

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

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

{} is a reference to an anonymous hash. So my %h = {} is equivalent to my %h = ({} => undef).

Perl requires hash keys to be strings, so when you use a reference as a key, Perl uses the reference's string representation (HASH(0x229e8)).

提笔落墨 2024-11-07 18:06:26
use Data::Dumper;

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

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

输出:

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

正如 rafl 所建议的,warnings pragma 会捕获这。
看看Greg Hewgill答案以获取更正后的代码。

use Data::Dumper;

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

%h gets assigned with a hash reference as the key and undef as the value.

Output:

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

As rafl suggested, the warnings pragma would have caught this.
Look at Greg Hewgill's answer for the corrected code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文