Perl 将哈希结构分配给标量变量

Perl 将哈希结构分配给标量变量,perl,hash,Perl,Hash,我有以下代码,其中我有一个结构($node),它是一个标量by声明,但似乎是一个hash by用法: sub LoadData() { #not significant code here my $node = { BaseName => "deviceA", SysDescr => "Example device", SysObjectI

我有以下代码,其中我有一个结构($node),它是一个标量by声明,但似乎是一个hash by用法:

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
);
my %hash = {
   #some foo => "bar" assign here
}
PS:它的行为类似于散列引用,因为AddDeviceData()将最后一个参数限制为散列引用


PSS:也许它与上下文有关;分配给标量的散列意味着分配对散列的引用,而不是散列本身的内容,但我不太确定。

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


有关Perl引用的详细介绍,请参阅

您介绍的三个示例的行为都不同:

my $hash = {
    foo => "bar",
};
使用单个键foo和值栏创建哈希引用,并将其分配给名为
$hash
的标量。散列引用中的值通过使用(->)后跟花括号和键名来访问;e、 g.
$hash->{foo};#条形码

my %hash = (
   foo => "bar",
);
my %hash = {
   foo => "bar",
}
使用单键foo和值栏创建哈希。使用大括号和键名访问散列中的值;e、 g.
$hash{foo};#条形码

my %hash = (
   foo => "bar",
);
my %hash = {
   foo => "bar",
}
尝试将哈希引用分配给哈希,从而有效地将匿名哈希引用作为密钥。由于Perl中的所有哈希键都是字符串,因此该键类似于值为
undef的
'hash(0x7f82948e1e1e18)
。如果你有
使用警告已启用(正如您应该看到的),在执行此行时,您将看到以下警告:

在test.pl行[行号]中找到了预期大小为偶数的列表的引用

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

我的意思是,在行为方面,两者之间有区别吗

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

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

  • {…}
    构造根据上下文创建匿名散列,并计算对该散列的引用,该散列是可分配给标量变量的标量值。大括号可能包含一个偶数编号的键/值对列表,用于初始化匿名散列中的数据

  • 语句
    my%hash={foo=>“bar”}
    是一个错误构造
    my%hash
    创建一个命名的hash,如上面的第一个实例,而
    {foo=>“bar”}
    创建另一个匿名hash,如第二种情况。匿名散列引用形成单个元素列表,并被字符串化以创建
    %hash
    元素的键。为缺少的值提供
    undef
    。它类似于

    my %anon = ( foo => 'bar' );
    my %hash - (\%anon, undef);
    
但是由于字符串化,密钥类似于
散列(0x633444)
,不能用于访问
%anon

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

my $href = { foo => 'bar' }
老式的方法是将引用当作散列名使用

$$href{foo}
或者,相同但更清晰

${$href}{foo}
或者有一个新的arrow解引用操作符,其工作原理与C语言中的相同,通常是首选

$href->{foo}

听起来您的大部分代码都是使用子例程原型编写的,而这些子例程原型在大多数语言中并不实用,应该仅限于非常特定的用途。此外,正常的Perl词汇变量应使用小写字母、数字和下划线命名:大写字母保留用于全局标识符。@Borodin感谢您对这两个主题的深入了解。第一点,关于原型,我将展望这些具体用途。关于词汇变量,这对我来说只是一件旧衣服。我下次会记得的。顺便说一下,这个示例代码不是我的,它来自我工作场所的某个前同事。我只是在学习和修改这些Perl的细微差别。这是公平的。我假设情况比这更糟,您工作的环境中的Perl标识符和子例程原型都是这样的标准。原型用于模块中,这些模块旨在向语言添加新的运算符,这些运算符与内置函数类似。您可以看到它们在中使用。恐怕我不会太注意你同事的工作:任何在Perl程序中使用子程序原型的人都不太熟悉所学的语言课程。找到了关于这个主题的前一个主题,如果像我这样的Perl新手想了解更多的话:谢谢@hunter mcmillen<代码>在预期大小为偶数的列表处找到引用
。。。解释“与bug相反”的常见或罕见错误(即perl是正确的,即使它是错误的)是理解语言机制的一个好方法,可以说比解码“模糊perl”更有用。