我正在编写一个Perl脚本并编写了一个子程序来检查我的哈希中是否存在密钥。这是子程序的内容:
sub _check_existence {
my $lib = $_[0];
while( my( $key, $value ) = each (%{$MyHash{sub_keys}}))
{
if ($key =~ $lib)
{
return 1;
}
}
return 0; }
问题在于,每次运行该功能时,它都会从上次运行开始。
例如,如果哈希包含密钥0
1
2
3
4
5
6
{{1} } 7
,第一次调用子程序寻找键8
时它会找到它。但是,如果我再次调用子程序寻找3
,我将得到 false ,因为迭代从3
继续,而不是从开始。
有人可以解释导致这种情况的原因吗?
答案 0 :(得分:4)
each
存在一个问题,正如您所发现的那样,它会为记住迭代位置的每个哈希保留一个内部状态
您可以通过调用keys %MyHash
来重置该状态,以便您的子程序变为
sub _check_existence {
my ($lib) = @_;
while ( my ( $key, $value ) = each %{ $MyHash{sub_keys} } ) {
if ( $key =~ /$lib/ ) {
keys %{ $MyHash{sub_keys} };
return 1;
}
}
return;
}
但是,您所编写的是一个子例程,它检查散列的任何键是否包含传递的参数作为子串,这是一个奇怪的要求。如果你的意思是检查是否相等那么你应该使用哈希的基本属性 - 它被其键索引,并且有一个内置的运算符:你可以写
exists $MyHash{sub_keys}{$_[0]};
如果你真的想要检查子字符串而不是简单的相等,那么还有另一种选择。您永远不会使用$value
,因此您只需要提供哈希的键列表。 keys
运算符与each
没有相同的问题,因为它不是设计为在标量上下文中每次调用时返回下一个键/值对。所以你可以写这个
sub _check_existence {
my ($lib) = @_;
for my $key ( keys %{ $MyHash{sub_keys} } ) {
return 1 if $key =~ /$lib/;
}
return;
}
最后我会说在子程序中使用全局%MyHash
有点难看。它应作为另一个子例程参数