将散列结构分配给标量变量

Assigning an hash structure to a scalar variable

我有以下代码,其中我有一个结构($node),声明为标量,但使用起来似乎是散列:

sub LoadData()
 {
     #not significant code here

     my $node = {
                    BaseName => "deviceA",
                    SysDescr => "Example device",

                    SysObjectId => "SysObjectIdTest",

                    ManagementIpAddress => "BLABLABLA",
                    Protocol => "1",

               };

     $store->AddDeviceData( 1, $node->{BaseName}, $node );
 }  

我的问题是:如上所示声明的 $node 是散列还是标量?我的意思是,

之间是否存在差异(就行为而言)
my $hash = {
    #some foo => "bar" assign here
};

my %hash = (
   #some foo => "bar" assign here
);

 my %hash = {
   #some foo => "bar" assign here
}

PS:它表现为散列引用,因为 AddDeviceData() 将最后一个参数限制为散列引用。

PSS:可能跟语境有关;将散列分配给标量意味着分配对散列的引用而不是散列本身的内容,但我不太确定。

{ key => value } 语法是一个匿名散列引用构造函数。引用是标量(它们基本上是花哨的指针)所以这就是为什么它被分配给一个标量变量。正如您在您指出的代码示例中注意到的那样,要获取底层哈希中的数据,您需要使用取消引用运算符 ->。要获取整个底层哈希,您可以使用 %$node

有关 Perl 参考资料的简要介绍,请参阅 Perl References Tutorial

您提供的所有三个示例的行为都不同:

my $hash = {
    foo => "bar",
};

使用单个键 foo 和值 bar 创建哈希引用并将其分配给名为 $hash 的标量。哈希引用中的值通过使用 arrow operator (->) 后跟大括号和键的名称来访问;例如$hash->{foo}; # bar

my %hash = (
   foo => "bar",
);

创建一个具有单个键 foo 和值 bar 的散列。散列中的值使用花括号和键的名称进行访问;例如$hash{foo}; # bar

my %hash = {
   foo => "bar",
}

尝试将哈希引用分配给哈希,这 有效地 使匿名哈希引用成为密钥。由于 Perl 中的所有散列键都是字符串,因此键类似于 'HASH(0x7f82948e1e18)',值为 undef。如果您启用了 use warnings;(您应该启用),则在执行此行时您会看到以下警告:

Reference found where even-sized list expected at test.pl line [line-number].

阅读 Perl 参考文档可能会有用:perldoc perlref

I mean, is there a difference (in terms of behavior) between

my $hash = {
    #some foo => "bar" assign here
};

and

my %hash = (
   #some foo => "bar" assign here
);

and

my %hash = {
   #some foo => "bar" assign here
}
  • my %hash 创建一个 命名的词法散列 ,它可以单独初始化或在声明中初始化 - 使用偶数列表 key/value对。每个键必须是一个简单的字符串,每个值都表现为 Perl 标量变量

  • { ... } 构造根据上下文创建一个 匿名 散列,并评估对该散列的引用——一个标量值,可以分配给一个标量变量。大括号可能包含 key/value 对的偶数列表,这些对在匿名散列

  • 中初始化数据
  • 语句my %hash = { foo => "bar" }是一种误解。 my %hash 创建一个命名哈希,如上面的第一个实例,而 { foo => "bar" } 创建另一个匿名哈希,如第二种情况。匿名哈希引用形成一个 单元素 列表,并被字符串化以创建 %hash 的元素的键。为缺失值提供了值 undef。它类似于

    my %anon = ( foo => 'bar' );
    my %hash - (\%anon, undef);
    

但是因为字符串化,key是类似HASH(0x633444)的东西,不能用来访问%anon

可以通过两种方式访问​​匿名散列的元素。例如,给定

my $href = { foo => 'bar' }

老式的方法是像使用哈希名称一样使用引用

$$href{foo}

或者,相同但更清晰

${$href}{foo}

或者有一个更新的箭头解引用运算符,它的工作原理与 C 语言中的相同,通常是首选

$href->{foo}