在 Perl 中,操作符 defined 检查值是否已定义(是否为 undef)。重要的是要区分:
defined($x) 返回 true,如果 $x 不等于 undef(无论值是什么,即使是空字符串或 0)。defined($hash{$key}) 检查元素的值是否已定义,但不保证该键本身存在。defined($array[$i]) — 类似,元素可能已定义,但数组的长度可能更长或更短。exists 来检查哈希中键的存在性。示例:
my %h = (a => undef); if (exists $h{a}) { print "键 'a' 存在 "; } if (defined $h{a}) { print "键 'a' 已定义 "; } else { print "键 'a' 未定义 "; }
结果:
键 'a' 存在
键 'a' 未定义
exists $hash{$key}和defined $hash{$key}的区别是什么?在何种情况下对哈希进行 defined 检查会得出意想不到的结果?
答案: defined $hash{$key} 检查值,但如果键不存在,则会返回未定义值。如果键存在,但其值为 undef,defined 返回 false。但如果键不存在 — 也返回 false。因此,始终使用 exists 来检查键的存在性。
示例:
my %h = (foo => undef); if (defined $h{foo}) { ... } # false if (exists $h{foo}) { ... } # true
故事
在一个项目中,检查“准备”标志为
defined($status{$id}),如果值为 undef,则认为任务未处理。然而,具有 undef 的键是有效的,并且没有进行 exists 的检查 — 因此,部分已处理的数据被重复执行。
故事
一位程序员在从文件导入数据时,比较字符串如下:
if (defined $line && $line ne '')。问题在于:有时 $line 可能是空字符串 '0'。这样的字符串并不为空,但与 defined 的比较(而不是检查 ne '')导致这些字符串丢失。
故事
在一个大 Perl 脚本中,处理哈希时,唯一的元素存在性检查是 defined — 结果是对于值为 undef 的键,出现了 bug 和在报告中遗漏的数据。