我需要验证存在并定义的散列元素(如$Table{$key1}{$key2}
)的Perl散列。这就是我的工作。 (我不知道$key1
甚至存在)
if
((defined $Table{$key1}) &&
(exists $Table{$key1}) &&
(defined $Table{$key1}{$key2}) &&
(exists $Table{$key1}{$key2}))
{
#do whatever
}
有更简单,更清洁的方法吗?
答案 0 :(得分:8)
你不需要检查层次结构的每个级别:你可以只追求你关心的价值。 exists
不检查定义,只有散列中的槽存在(它可能存在未定义的值),所以如果你关心定义了值,你需要调用defined
而不是存在。如果没有定义一个值,它在布尔上下文中的计算结果为false,所以我们可以输入一点,并将你的例子减少到:
if ($Table{$key1}{$key2})
{
# do whatever
}
但是,如果该键中的值已定义但为“false”(数值计算为零,或者为空字符串),则可能导致误判,因此如果可能,我们应明确检查定义:
if (defined $Table{$key1}{$key2})
{
# do whatever
}
如果你不想自动审核$Table{$key1}
,你可以先检查它的存在,这会让我们看到一般案例的“最佳”方式:
if (exists $Table{$key1} and defined $Table{$key1}{$key2})
{
# do whatever
}
如果你要为哈希中的各个字段做很多事情,你可能想要添加一些OO风格的访问器方法,这些方法可以帮到你:
sub has_field
{
my ($this, $fieldName) = @_;
return exists $this->{data} && defined $this->{data}{$fieldName});
}
我确定你已经阅读过了,但再次阅读相关文档并不会有什么坏处:
给定一个指定哈希元素或数组元素的表达式,如果哈希值或数组中的指定元素已被初始化,则
exists
返回true,即使相应的值未定义。如果元素不存在,则该元素不会自动生成 ...
散列或数组元素只有在定义时才为真,如果存在则定义,但反过来不一定适用。
答案 1 :(得分:6)
以下内容较短,可防止自动生成:
if (exists $table{$key1} and defined $table{$key1}{$key2}) {...}
不需要代码中的其他检查。
答案 2 :(得分:1)
首先检查存在,然后检查定义。 (值可以不经定义而存在但不能在没有现有的情况下定义。)您应该使用exists
测试中间级别以防止意外的自动更新。对于最后一级,您只需要致电defined
。当没有太多层时,可以直接编码:
if (exists $hash{a} && defined $hash{a}{b}) {...}
如果有很多层,这会变得很尴尬:
if (exists $hash{a} && exists $hash{a}{b} && exists $hash{a}{b}{c} ...) {...}
在这种情况下,您可以编写一个defined
版本,该版本不会自动生成中间值:
sub safe_defined {
my $h = shift;
foreach my $k (@_) {
if (ref $h eq ref {}) {
return unless exists $h->{$k};
$h = $h->{$k};
}
else {
return;
}
}
return defined $h;
}
你这样使用它:
if (safe_defined(\%hash, qw(a b c))) {
say $hash{a}{b}{c};
}
注意:此版本的功能有限。
真正的通用版本留给读者练习。 ;)
答案 3 :(得分:1)
您可以查看Data::Diver。它潜入数据结构而不进行自动更新。语法如下:
if ( defined Dive(\%Table, $key1, $key2) ) { ... }
甚至:
if ( defined(my $value = Dive(\%Table, $key1, $key2) ) ) {
...do something with $value...
}
答案 4 :(得分:0)
大!谢谢大家的回复。
由于autvivifying对我来说是一个问题,目前我正在使用“尴尬”的方法,即 if(存在$ Table {$ key1}&& defined $ Table {$ key1} {$ key2}){
}
它适用于我,但正如你们所说,我有3-4级深度的嵌套哈希,代码有点乱。
我将查看数据:潜水员。那个看起来更好。
再次感谢,