0

我在我的代码中使用哈希表

my %stat = ();
# read files and do some initialization 
# like  $stat{$key} = {k1=>v1, k2=>v2, k3=>v3};
#   I have located the buggy code
# I want to do something according to c1 and c2 parsed from each line of the file
if(!exists $stat{c1}) {   # I thought I would have initialized all possible used keys here, but it is not true as seen below
    $stat{c1} = {k1=>0, k2=>0, k3=>0};
} 
if( $c1 == $c2) {
    $stat{c1}{k1}++;
} else {
    $stat{c1}{k2}++;
    $stat{c2}{k3}++;  #Note: I forgot to check whether $stat{c2} has been initialized here!
}



map {
    my $val = $stat{$_}{k1};  
    print "$val\n";     # run time error shows "use of uninitalized $val"
} keys %stat;

我写了一些打印语句来调试程序。我发现哈希表“%stat”中神秘地出现了一些键值,尽管我从未插入过它!假设 $stat{510} 以某种方式存在,尽管我从未插入它,但它的值(在我的例子中是哈希表引用)没有初始化。我必须写一个声明:

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat;

删除不需要的密钥。

你能告诉我为什么会从(keys %stat)中出现一些神秘的钥匙吗?

谢谢,杰夫

4

2 回答 2

9

你能告诉我为什么会从(keys %stat)中出现一些神秘的钥匙吗?

因为您没有显示的代码以某种方式创建了它们。

也许你做到了$stat{510}{k1}?请记住,

$stat{510}{k1}

简称

$stat{510}->{k1}

$x->{...}

( $x //= {} )->{...}

所以

$stat{510}{k1}

( $stat{510} //= {} )->{k1}

请注意这是如何分配给 的$stat{510}


不赞成使用map作为for循环。

map { delete $stat{$_} if(!defined $stat{$_}{k1}) } keys %stat;

最好写成

delete $stat{$_} for grep !defined($stat{$_}{k1}), keys %stat;

甚至

delete @stat{ grep !defined($stat{$_}{k1}), keys %stat };
于 2013-03-15T22:03:51.483 回答
2

因为自动复活。这意味着当您引用哈希条目时,它会毫无怨言地创建。如果你当时没有赋值,它会被初始化为undefined. 因此,在您拥有的代码部分中

##read files and do some initialization 

确保您没有使用 key 读取或写入条目510

于 2013-03-15T21:59:45.973 回答