undef、初始值、以及 defined 函式
各程式語言多半有特殊的方式來表達「此處沒有值」的概念。在 SQL、PHP、 Java 裡,是 NULL,在 Python 為 None, 在 Ruby 則為 Nil。
而在 Perl 裡,則是 undef。
細節分曉如後。
undef 從何而來?
在宣告純量變數時,如果沒有即時賦值,那就表示這個變數的內容定為 undef。
my $x;
有些函式,以傳回 undef 來表示某種錯誤發生。而另外有些函式則用此招來表示沒有傳回值。
my $x = do_something();
另外還有個 undef() 函式,可將變數的值改成 undef:
undef $x;
也可以把 undef() 函式的傳回值,賦予某個變數,這麼一來該變數的值也會變成 undef:
$x = undef;
函數後頭的小括號可以省略,因此在範例中一律不出現。
如前各例,要將變數的值改成 undef,有好幾種方式。不過真正問題在於,如果 程式碼中對此值進行了運算,那會發生甚麼事?
在談論到這點之前,先離題看點別的:
如何檢查某個值或變數等於 undef?
使用 defined() 這個函式,如果傳入的參數不等於 undef,便會傳 回 true。反之,則會傳回 false。
使用範列如下:
use strict; use warnings; use 5.010; my $x; # 假設這裡有段程式碼,可能會改到 $x 的值 if (defined $x) { say '$x is defined'; } else { say '$x is undef'; }
所以, undef 真正代表的值是什麼呢?
雖然 undef 基本上表示沒有值,但並非不能拿來運算。Perl 算符在碰到 undef 值 時,提供兩種不同的運算用的預設值。
如果某個數值運算中用到的變數,其值為 undef,可視其為 0。
如果在字串運算中與到了 undef,則視其為空字串。
例如:
use strict; use warnings; use 5.010; my $x; say $x + 4, ; # 4 say 'Foo' . $x . 'Bar' ; # FooBar $x++; say $x; # 1
在前例中,變數 $x 的預設值為 undef,但在之後的加法運算(+)裡,其作用與 0 相同。 而在之後的字串接續算式(.)裡,則變身為空字串。最後又有一次遞加運算(++),再次以 0 取代。
但這機制並非無瑕。如果在程式中寫了 use warnings,啟用警告機制 (強力推薦使用),那麼在執行程 式時會印出兩次「use of unitialized value」警告訊息,不過最後一次的遞加運算不會有警告。
Use of uninitialized value $x in addition (+) at ... line 6. Use of uninitialized value $x in concatenation (.) or string at ... line 7.
這麼看來遞加算符似乎比較寬恕一些。在其他篇章可以看到,在進行計數時,這樣的特性會讓使事情變得很方便。
當然,也可以在變數宣告時就賦予初始值(0 或空字串,視情況而定),或著視不同時機關掉警告機制。在其他篇章另述。
Published on 2013-04-10