說明
在電腦程式中,資料型態用來界定資料所占的記憶體大小及該資料合法的操作,像是數字間可進行四則運算,字串可相接等。
Perl 的內建資料型態如下:
- 純量 (scalar)
- 數字 (number)
- 字串 (string)
- 參考 (reference)
- 陣列 (array)
- 雜湊 (hash)
純量是單獨的值,陳列、雜湊則是容器。純量本身沒有綁定特定型態。寫 Perl 程式時也不需要宣告純量的型態,Perl 會自動判定純量當下的型態,並視需求自動轉換。
除了內建型態,Perl 有一套相對原始的物件系統。我們在先前的文章有說過,Perl 在當代的定位是有程式語言的命令列工具。對於學習 Perl 來說,物件系統不是很必要。
數字 (Number)
Perl 的數字可能是整數 (integer) 或浮點數 (floating-point numbers),支援以下表示法:
my $x = 12345; # integer
my $x = 123.45; # floating point
my $x = 6.02e23; # scientific notation
my $x = 1000_000_000; # long int with better readability
my $x = 0377; # octal
my $x = 0xff; # hexadecimal (hex)
my $x = 0b1100_0000; # binary
前四個數字為一般常見的十進位數。但 Perl 支援其他進位系統:
0
開頭表示八進位數0x
開頭表示十六進位數0b
開頭表示二進位數
要將字串轉為相對應的數字時,可用以下函式:
int
:去除小數點部分,僅回傳整數oct
:轉成二進位、八進位、十六進位數- 浮點數可自動轉換
浮點數的誤差
由於浮點數內部儲存的方式,進行浮點數運算時有可能會引入微小的誤差。見下例:
my $n = 0;
while ($n != 1) {
# Do something here.
$n += 0.1;
}
在理想的狀態下,$n
每跑一輪迴圈會遞增 0.1
,跑十輪後就可以終止此 while
迴圈。但是,每次進行小數運算時會引進微小的誤差,實際上 $n
會跳過 1
後繼續遞增,造成非預期的無窮迴圈。
解決浮點數誤差的想法如下:
|實際值 - 誤差值| < 誤差
要注意誤差無法消除,只能藉由運算儘可能地縮小誤差到合理的範圍內。
我們將前例改寫如下:
my $n = 0;
while (abs($n - 1) > 1 / 100000) {
# Do something here.
$n += 0.1;
}
隨著 $n
遞增,誤差會逐漸縮小,最後在滿足條件時迴圈會結束。這並不是 Perl 獨有的問題,而是大部分程式語言會碰到的議題。
只有 Raku 等少數語言可以進行精準的小數點運算,但實務上幾乎不會有程式人用 Raku 進行數值運算,不能過度依賴 Raku 等少數語言所提供的特性。
字串 (String)
字串實字可用一對 ''
(單引號) 或是一對 ""
(雙引號) 包起來,兩者的差別在於前者不會進行字串安插 (string interpolation) 而後者會。
以下是實例:
my $name = "ByteBard";
'Hello $name' == "Hello \$name" or die "Wrong value";
"Hello $name" == "Hello ByteBard" or die "Wrong value";
在使用單引號包住 Hello $name
時,$name
不會插入實際的值,而會保持字面上的字元;相對來說,使用雙引號包住同一字串時,$name
會代換成 "ByteBard"
,所以會得到不同的結果。
\
(slash) 在雙引號字串的意思是跳脫下一個字元原本的意思,像是 \$
代表不要解析 $
而把其視為普通字串。有些字母會有特殊意義,如下:
\n
:換行\t
:插入 TAB\\
:將下一個\
視為普通字串\$
:將下一個$
視為普通字串
這裡有更多的跳脫字元,讀者可自行參考。
特殊字串括號
除了原本的單/雙引號之外,Perl 還支援另一套寫法:
q//
:相當於單引號字串qq//
:相當於雙引號字串qx//
:將字串視為命令列程式來執行qw//
:字串串列qr//
:正規表示式
為什麼要引入這套寫法呢?這是為了避免過多的 \
(slash),如下例:
my $name = "ByteBard";
qq("Perl is awesome!", $name said.) eq "\"Perl is awesome!\", $name said."
or die "Wrong value";
使用正規的雙引號字串時,我們要跳脫內部的雙引號,以免字串提早結果,但用 qq()
代替雙引號時,則不需跳脫內部的雙引號,可簡化程式碼。
自動型態轉換
Perl 會根據程式所在的情境境自動將資料轉換型態。如下例:
"2" * 3 == 6 or die "Wrong value\n";
Perl 程式會自動將字串 "2"
轉為數字 2
後進行運算。這樣的程式碼不是好的寫法,只是用來展示 Perl 的特性。
參考 (Reference)
參考是相對進階的概念,主要用於製作複合資料結構 (complex data structures),像是多維陣列或是混合陣列及雜湊的結構等。初階的 Perl 程式不會用到參考。
陣列 (Array)
陣列是線性 (linear)、有序的 (ordered) 容器。我們會在後文介紹陣列。
雜湊 (Hash)
雜湊是以鍵值對 (key-value pair) 為儲存單位的非線性 (non-linear) 容器。我們會在後文介紹雜湊。