存在和定义有什么区别?

有什么区别

if (defined $hash{$key}) { } 

 if (exists $hash{$key}) { } 

我什么时候知道使用哪个?

这是perldoc条目中已definedexists 。 这里有一个简要的总结:

defined $hash{key}告诉你给定键的值是否被定义(即不是undef )。 用它来区分未定义的值和在布尔上下文(如0''中为false的值。

exists $hash{key}告诉你%hash是否包含给定的键值。 用它来区分未定义的值和不存在的值。

这是最容易看到一个例子。 鉴于这个哈希:

 my %hash = (a => 1, b => 0, c => undef); 

以下是检索,定义和存在的结果:

 # key value defined exists a 1 1 1 b 0 1 1 c undef 0 1 d undef 0 0 

在实践中,人们通常只是写if ($hash{key}) {...}因为(在许多常见的情况下)只有真正的值是有意义的/可能的。 如果false值有效,则必须defined()添加到testing。 exists()用得less得多。 最常见的情况是使用散列作为一个集合。 例如

 my %set = map { $_ => undef } 'a' .. 'z'; 

使用undef设置值有一些优点:

  1. 它更准确地expression意图(只有键是有意义的,而不是值)。
  2. 所有的undef值共享一个分配(这可以节省内存)。
  3. exists()testing稍微快一些(因为Perl不必检索值,只能确定是否有)。

它也有缺点,你必须使用exists()来检查设置成员资格,这需要更多的input,如果你忘记了会做错误的事情。

另一个exists地方是有用的是在尝试检索一个值(这将触发exception)之前探测locking的散列。

defined检查variables的值, exists检查它是否曾经被声明/初始化。 如果存在,简单明了。

例如:

 $hash{$key} = undef; # various return values: exists $hash{$key}; # true defined $hash{$key}; # false $hash{$key}; # false $hash{$key} = 0; # various return values: exists $hash{$key}; # true defined $hash{$key}; # true $hash{$key}; # false exists $hash{$foo}; # false 

Perl 文档 :

在散列元素上使用时, 定义将告诉您是否定义了该值,而不是密钥是否存在于散列中。 存在用于后一个目的。

正如perldoc中所述:

给定一个指定哈希元素的expression式,如果哈希中的指定元素已经被初始化,则返回true,即使对应的值是未定义的。

散列或数组元素只有在定义和定义的情况下才可以为真,但是相反并不一定成立。

也就是说,一个散列可以包含一个未定义的元素,如果是这样的话, defined -check将返回false ,而exists -check将返回true

因此,如果您希望知道给定条目是否存在于散列中,那么应该使用exists ,并且如果您想知道给定条目是否存在并且已定义,则应该使用exists

这个例子显示了不同之处。 在一般定义的作品为任何结构存在与散列有关。

 my %hash=("1"=>undef); print "exists:".exists($hash{"1"})."\n"; print "defined:".defined($hash{"1"})."\n"; 

差别不大,不太明显,所以期望人们会乱它。