存在和定义有什么区别?
有什么区别
if (defined $hash{$key}) { }
和
if (exists $hash{$key}) { }
我什么时候知道使用哪个?
这是perldoc条目中已defined
和exists
。 这里有一个简要的总结:
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
设置值有一些优点:
- 它更准确地expression意图(只有键是有意义的,而不是值)。
- 所有的
undef
值共享一个分配(这可以节省内存)。 -
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";
差别不大,不太明显,所以期望人们会乱它。