为什么 perl 会在我的散列中插入一个 undef 值?
Why does perl insert an undef value into my hash?
让我从一个简单的最小示例开始:
use strict;
use warnings;
use Data::Dumper;
my %hash;
$hash{count} = 4;
$hash{elems}[$_] = {} for (1..$hash{count});
print Dumper \%hash;
这是结果(重新格式化):
$VAR1 = {
'count' => 4,
'elems' => [undef, {}, {}, {}, {}]
};
不明白,为什么$hash{elems}
的第一个元素变成了undef
?
我知道可能有更简单的方法来做我正在做的事情,但我正在创建这些空哈希,以便我以后可以做 my $e = $hash{elems}[$i]
并继续使用 $e
与元素,例如使用 $e->{subelems}[0] = 100
.
继续嵌套结构的恐怖
Perl 中的数组索引从 0
开始(在大多数编程语言中也是如此)。
在 $hash{elems}[$_] = {} for (1..$hash{count});
的第一次迭代中,$_
是 1
,因此您将 {}
放在 $hash{elems}
的索引 1
处.
由于您没有在 $hash{elems}
的索引 0
处放置任何内容,它包含 undef
.
要解决这个问题,您可以使用 push
而不是分配给特定索引:
push @{$hash{elems}}, {} for 1 .. $hash{count};
push
在第一个参数的末尾添加项目。最初,$hash{elems}
是空的,所以结尾是第一个索引 (0
)。
一些提示:
for (1..$hash{count})
中不需要括号:for 1 .. $hash{count}
效果一样,看起来更轻一些。
您可以在声明哈希时初始化它:
my %hash = (
count => 4,
elems => [ map { {} } 1 .. 4 ]
);
使用 hashrefs 的 arrayref 初始化 elems
通常是无用的,这要归功于 autovivification。简单地执行 $hash{elems}[0]{some_key} = 42
将在 $hash{elems}
中创建一个 arrayref,该数组中索引 0
处的 hashref,包含键 some_key
和值 42
.
但在某些情况下,您的初始化可能有意义。例如,如果你想将 $hash{elems}
(但不是 $hash
)传递给一个函数(如果你想将 $hash{elems}[..]
传递给一个函数而不传递 $hash{elems}
也是一样)。
让我从一个简单的最小示例开始:
use strict;
use warnings;
use Data::Dumper;
my %hash;
$hash{count} = 4;
$hash{elems}[$_] = {} for (1..$hash{count});
print Dumper \%hash;
这是结果(重新格式化):
$VAR1 = {
'count' => 4,
'elems' => [undef, {}, {}, {}, {}]
};
不明白,为什么$hash{elems}
的第一个元素变成了undef
?
我知道可能有更简单的方法来做我正在做的事情,但我正在创建这些空哈希,以便我以后可以做 my $e = $hash{elems}[$i]
并继续使用 $e
与元素,例如使用 $e->{subelems}[0] = 100
.
Perl 中的数组索引从 0
开始(在大多数编程语言中也是如此)。
在 $hash{elems}[$_] = {} for (1..$hash{count});
的第一次迭代中,$_
是 1
,因此您将 {}
放在 $hash{elems}
的索引 1
处.
由于您没有在 $hash{elems}
的索引 0
处放置任何内容,它包含 undef
.
要解决这个问题,您可以使用 push
而不是分配给特定索引:
push @{$hash{elems}}, {} for 1 .. $hash{count};
push
在第一个参数的末尾添加项目。最初,$hash{elems}
是空的,所以结尾是第一个索引 (0
)。
一些提示:
for (1..$hash{count})
中不需要括号:for 1 .. $hash{count}
效果一样,看起来更轻一些。您可以在声明哈希时初始化它:
my %hash = ( count => 4, elems => [ map { {} } 1 .. 4 ] );
使用 hashrefs 的 arrayref 初始化
elems
通常是无用的,这要归功于 autovivification。简单地执行$hash{elems}[0]{some_key} = 42
将在$hash{elems}
中创建一个 arrayref,该数组中索引0
处的 hashref,包含键some_key
和值42
.
但在某些情况下,您的初始化可能有意义。例如,如果你想将$hash{elems}
(但不是$hash
)传递给一个函数(如果你想将$hash{elems}[..]
传递给一个函数而不传递$hash{elems}
也是一样)。