exists EXPR

给定一个指定哈希元素的表达式,如果哈希中的指定元素已初始化,即使相应的值未定义,则返回 true。

print "Exists\n"    if exists $hash{$key};
print "Defined\n"   if defined $hash{$key};
print "True\n"      if $hash{$key};

exists 也可以在数组元素上调用,但其行为不太明显,并且与在数组上使用 delete 紧密相关。

警告:强烈建议不要在数组值上调用 exists。删除或检查 Perl 数组元素的概念在概念上不连贯,并且可能导致令人惊讶的行为。

print "Exists\n"    if exists $array[$index];
print "Defined\n"   if defined $array[$index];
print "True\n"      if $array[$index];

哈希或数组元素只有在定义时才为 true,只有在存在时才定义,但反之不一定成立。

给定一个指定子例程名称的表达式,如果指定子例程已声明,即使未定义,则返回 true。为 exists 或 defined 指定子例程名称不算声明它。请注意,不存在的子例程仍然可以调用:其包可能有一个 AUTOLOAD 方法,使其在第一次调用时立即生效;请参阅 perlsub

print "Exists\n"  if exists &subroutine;
print "Defined\n" if defined &subroutine;

请注意,只要最终操作是哈希或数组键查找或子例程名称,EXPR 就可以任意复杂

if (exists $ref->{A}->{B}->{$key})  { }
if (exists $hash{A}{B}{$key})       { }

if (exists $ref->{A}->{B}->[$ix])   { }
if (exists $hash{A}{B}[$ix])        { }

if (exists &{$ref->{A}{B}{$key}})   { }

虽然最深层嵌套的数组或哈希元素不会仅仅因为测试了它的存在而突然出现,但任何中间元素都会出现。因此,由于上面对 $key 元素的存在性测试,$ref->{"A"}$ref->{"A"}->{"B"} 将突然出现。无论箭头运算符在哪里使用,都会发生这种情况,甚至包括这里

undef $ref;
if (exists $ref->{"Some key"})    { }
print $ref;  # prints HASH(0x80d3d5c)

将子例程调用(而不是子例程名称)用作 exists 的参数是一个错误。

exists ⊂    # OK
exists &sub();  # Error