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;

プログラムをデバッグするためのprintステートメントを作成しました。挿入したことがないにもかかわらず、ハッシュテーブル "%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 

キーを使用してエントリを読み書きしていないことを確認してください510

于 2013-03-15T21:59:45.973 に答える