直接 perl 散列引用和转换为引用的散列之间的区别

Difference between a direct perl hash reference and a hash that is turned into a reference

我试图理解此处给出的代码示例:https://www.perlmonks.org/?node_id=1083257 以及示例中给出的直接创建的散列引用与我首先创建的散列引用之间的区别。当我运行下面的代码:

use strict;
use warnings;
use Algorithm::NaiveBayes;

my $positive = {
    remit => 2,
    due => 4,
    within => 1,
};
my $negative = {
    assigned => 3,
    secured => 1,
};

my $categorizer = Algorithm::NaiveBayes->new;
$categorizer->add_instance(
    attributes => $positive,
    label => 'positive');
$categorizer->add_instance(
    attributes => $negative,
    label => 'negative');

$categorizer->train;

my $sentence1 = {
    due => 2,
    remit => 1,
};

my $probability = $categorizer->predict(attributes => $sentence1);

print "Probability positive: $probability->{'positive'}\n";
print "Probability negative: $probability->{'negative'}\n";

我得到结果:

Probability positive: 0.999500937781821
Probability negative: 0.0315891654410057

但是,当我尝试通过以下方式创建散列引用时:

my %sentence1 = {
    "due", 2,
    "remit", 1
};

my $probability = $categorizer->predict(attributes => \%sentence1);

我得到:

Reference found where even-sized list expected at simple_NaiveBayes.pl line 57.
Probability positive: 0.707106781186547
Probability negative: 0.707106781186547

为什么我的散列 \%sentence1 与示例中给出的 $sentence1 散列引用不同?

my %sentence1 = {
    "due", 2,
    "remit", 1
};

你做错了(你试图用一个键创建哈希,这是一个哈希引用(不起作用)并且没有对应的值)。这就是为什么 perl 会警告您查找引用而不是偶数大小的列表。你想要

my %sentence1 = (
    "due", 2,
    "remit", 1
);

就像警告所说的那样,您正在为预期大小为偶数的列表分配参考。这个

my %sentence1 = {   # curly bracers create a hash reference, a scalar value
    "due", 2,
    "remit", 1
};

应该是这样的

my %sentence1 = (   # parentheses used to return a list (*)
    "due", 2,
    "remit", 1
);

(*):括号实际上并不创建列表,它们只是覆盖优先级。在这种情况下 = 优于 ,=>,其中 returns 项目列表要分配。

或者这个

my $sentence1 = {    # scalar variable is fine for a reference
    "due", 2,
    "remit", 1
};

如果您想了解技术,散列分配中发生的事情是散列引用 { ... } 被字符​​串化并变成散列键。 (该字符串将类似于 HASH(0x104a7d0))该散列键的值将是 undef,因为您分配给散列的“列表”仅包含 1 个内容:散列引用。 (因此出现“偶数列表”警告)因此,如果您使用 Data::Dumper 打印这样的散列,您将得到如下所示的内容:

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