2011-06-30 94 views

回答

76

這充分證明在的perldoc條目definedexists。這裏有一個快速的總結:

defined $hash{key}告訴你是否定義給定鍵的值(即不是undef)。用它來區分未定義的值和布爾上下文中爲false的值,如0''

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}) {...}因爲(在很多常見的情況),只有真值是有意義的/可能的。如果虛假值有效,您需要defined()加入測試。 exists()的使用頻率要低得多。最常見的情況可能是使用散列作爲一個集合。例如

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

使用undef爲設定值有幾個優點:

  1. 它更精確地表示意圖(僅鍵是有意義,而不是值)。
  2. 所有的undef值共享一個分配(這可以節省內存)。
  3. exists()測試速度稍快(因爲Perl不必檢索值,只能確定有一個)。

它也有缺點,你必須使用exists()來檢查設置的成員資格,這需要更多的打字,如果你忘記了會做錯誤的事情。

exists有用的另一個地方是在嘗試檢索值(這將觸發異常)之前探測鎖定的散列。

+0

非常好解釋。 –

+0

另外,'defined'也可以用於其他類型的變量,而'exists'如果不用於散列或數組鍵(或子例程)將會拋出一個錯誤。 – felwithe

4

perldoc on exists指出:

鑑於指定的散列的一個元素的表達式中,如果在散列指定元素曾經被初始化返回true,即使相應的值是未定義的。

只有在散列或數組元素存在時才定義和定義散列或數組元素,但反過來並不一定成立。

也就是說,散列可以包含一個未定義的元素,並且如果是這樣的情況下,defined -check將返回false,而exists -check將返回true

因此,如果您想知道給定條目是否存在於散列中,您應該使用exists,如果您想知道給定條目是否存在並且已定義,您應該使用defined

+1

是的。 'exists'檢查哈希是否包含給定的鍵,但不檢查它的值,而'defined'則查看給定鍵的值,並查看它是否被定義(如果鍵不存在,它返回一個'undef',所以即使密鑰不在那裏它也可以工作。) –

3

這個例子顯示了區別。一般定義的作品適用於任何結構,存在與散列相關。

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

這個差別很小,不是很明顯,所以期望人們會亂它。

5

的Perl documentation

當散列元素上使用,定義告訴 值是否被定義,不 哈希是否存在的關鍵。 對於後一個目的,使用存在

14

defined檢查變量的值,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 
+0

而且'defined $ hash {$ foo}; #假設我想? –

+2

@Sandra是的,未初始化的值總是未定義的。可以把它看作聲明和初始化之間的區別:'my $ var'存在,並且包含值'undef'。 'my $ var = 0'存在,並且包含值0,因此被定義。 – TLP

+0

'$ hash {$ key}'返回'$ key'的值。雖然這可以解釋爲布爾值,但它不是一個。你的第一個例子應該返回'undef',第二個'0'。 –