在Perl中,未初始化的哈希键是否具有默认值零?

fre*_*ncy 8 perl hash default-value

我有类似于以下的Perl代码:

# -- start --

my $res;

# run query to fetch IPv6 resources
while( my $row = $org_ip6_res->fetchrow_arrayref )
{
    if( $row->[4] =~ /PA/ ) {
        $res->{ipv6}{pa}{$row->[2]}++;
    } elsif( $row->[4] eq 'PI' ) {
        $res->{ipv6}{pi}{$row->[2]}++;
    }
}

# -- stop --
Run Code Online (Sandbox Code Playgroud)

$res迭代查询结果之前没有设置过,但代码运行得很好.

当我在每个值之前放置print语句时,在两种情况下都会出现空白,但是如果在应用了增量之后出现了print语句,那么取决于组织拥有多少IPv6资源,我得到的值> = 1.

我的问题是,我是否认为这意味着Perl中未初始化的哈希键自动具有零值?

很抱歉,如果它是一个新手问题,但我只是不熟悉这样的结构,即$hashref->{foo}->{bar}++ 尚未明确指定值$hashref->{foo}->{bar}.提前致谢!

Tel*_*hus 26

该值不会自动为零.该值最初未定义.但是,如果您将其视为一个数字(例如,适用++于它),那么Perl会将其视为零.如果你将它视为一个字符串(例如,应用于.它),那么Perl将其视为空字符串.

来自perldoc perlsyn,在"声明"下:

你需要在Perl中声明的唯一事情是报告格式和子程序(有时甚至不是子程序).变量保存未定义的值("undef"),直到为其分配了一个定义的值,该值不是"undef".当用作数字时,"undef"被视为0; 当用作字符串时,它被视为空字符串""; 当用作未分配的参考时,将其视为错误.


dao*_*oad 5

要详细说明Telemachus的帖子,未初始化的值将是未定义的.结构的深部是自动生成的.这是一个方便的功能,可以自动为您创建数据结构.当你想要它时,自动复原很棒,但是当你想要防止它时它会很痛苦.在了解自动更新方面,网上有很多教程,文章和帖子.

因此,考虑不确定的$ref$ref->{ipv6}{pa}{'foo'}++,$ref将被分配一个值:

$ref = { 
     ipv6 => { 
          pa => { 
              foo => undef
          }
     }
};
Run Code Online (Sandbox Code Playgroud)

然后undef将递增,因为undef编号为0,我们得到0 ++,这是1.最终结果:ref->{ipv6}{pa}{'foo'} == 1.

如果您启用了警告,(您这样做use warnings;,不是吗?)当您对这些未定义的值进行操作时,您将收到"未初始化的值"警告.如果要增加酉值的所需行为,则可以在代码的有限部分中关闭所需的警告组:

use strict;
use warnings;
my $res;

// run query to fetch IPv6 resources
while( my $row = $org_ip6_res->fetchrow_arrayref )
{   no warnings 'uninitialized';
    if( $row->[4] =~ /PA/ ) {
        $res->{ipv6}{pa}{$row->[2]}++;
    } elsif( $row->[4] eq 'PI' ) {
        $res->{ipv6}{pi}{$row->[2]}++;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在perllexwarn中找到警告层次结构.

  • ++和 - 运算符不会警告使用未初始化的值.相反,他们默默地将undef转换为0. (2认同)