前言
運算子 (operators) 可執行一些基本的運算,會透過符號而非函式呼叫來使用。一般來說,運算子無法再拆分成更細的項目,所以視為程式語言的基本指令。
不過,有許多語言支援運算子重載 (operator overloading),若某參考型別 (或物件) 重載了某個運算子,該物件就可以像基礎型別般使用運算子。Perl 也支援運算子重載,但我們不在本文介紹這個部分,僅介紹基本的運算子使用方式。
代數運算子 (Arithmetic Operators)
代數運算是指基本的四則運算,包括以下運算子:
+
:相加-
:相減*
:相乘/
:相除%
:取餘數**
:取指數
以下是實例:
7 + 3 == 10 or die "Wrong value";
7 - 3 == 4 or die "Wrong value";
7 * 3 == 21 or die "Wrong value";
7 / 3 - 2.333333 < 1 / 100000 or die "Wrong value";
7 % 3 == 1 or die "Wrong value";
7 ** 3 == 7 * 7 * 7 or die "Wrong value";
我們在這裡說明一下 die
的使用方式。die
是 Perl 用來拋出例外的函式 (參考這裡),在這裡用來模擬其他語言的斷言 (assertion),該行程式能順利執行代表程式的條件句為真 (true)。
要注意 /
(相除) 的結果會是浮點數;相對來說,%
(取餘數) 的結果則會是整數。
關係運算子 (Relational Operators)
關係運算子用於比較兩項資料的大小。Perl 根據比較值為字串或數字需要使用不同的運算子,這是因為 Perl 為弱型別語言,無法直接以帳面上的值判定型別。
以下是 Perl 之中支援數字比較的運算子:
==
:相等!=
:不相等<=>
:相等或不相等>
:大於>=
:大於等於<
:小於<=
:小於等於
以下是使用實例:
3 == 3 or die "Wrong relation";
7 != 3 or die "Wrong relation";
7 > 3 or die "Wrong relation";
7 >= 3 or die "Wrong relation";
3 < 7 or die "Wrong relation";
3 <= 7 or die "Wrong relation";
在這些運算子中,<=>
可以同時判定大於、等於、小於三種情境,會分別回傳 1
、0
、-1
。參考下例:
(7 <=> 3) > 0 or die "Wrong relation";
在此處,建議寫 > 0
而不要寫 == 1
,因為 <=>
運算子的精神在於用數字的正負判定大小,而非死記回傳的數值。
以下是支援字串比較的運算子:
eq
:相等ne
:不相等cmp
:等於或不等於gt
:大於ge
:大於或等於lt
:小於le
:小於或等於
使用方式和數字比較相似。以下是實例:
"Perl" eq "Perl" or die "Wrong relation";
"Perl" ne "Ruby" or die "Wrong relation";
"Perl" lt "Ruby" or die "Wrong relation";
"Perl" le "Ruby" or die "Wrong relation";
"Ruby" gt "Perl" or die "Wrong relation";
"Ruby" ge "Perl" or die "Wrong relation";
因為 "R"
在順位上比 "P"
後面 (大),所以會有這樣的比較結果。
如果有在用類 Unix 系統的讀者,會發現 Perl 的關係運算子剛好和 Bash 的關係運算子相反。筆者以為 Perl 的運算子比較好記,因為數字用符號來相較而字串用字串來相較。
邏輯運算子 (Logic Operators)
邏輯運算子用來進行邏輯運算,在實務上用於結合兩個以上的判斷式。Perl 有兩套邏輯運算子,符號型的優先順序較高,而文字型的優先順序幾乎是最低的。以下是高優先順序的邏輯運算子:
&&
:且 (and)||
:或 (or)!
:非 (not)
參考以下例子:
my $true = 1;
my $false = 0;
# AND
($true && $true) == $true or die "Wrong logic";
($true && $false) == $false or die "Wrong logic";
($false && $true) == $false or die "Wrong logic";
($false && $false) == $false or die "Wrong logic";
# OR
($true || $true) == $true or die "Wrong logic";
($true || $false) == $true or die "Wrong logic";
($false || $true) == $true or die "Wrong logic";
($false || $false) == $false or die "Wrong logic";
# NOT
!$true == $false or die "Wrong logic";
!$false == $true or die "Wrong logic";
由於 Perl 沒有真正的真偽值,故我們在範例中分別將 1
和 0
做為 $true
和 $false
。
以下則是低優先順序的邏輯運算子:
and
:且or
:或xor
:互斥或not
:非
註:xor
僅在兩者真偽相異時才會成立。
以下是範例:
my $true = 1;
my $false = 0;
# AND
($true and $true) == $true or die "Wrong logic";
($true and $false) == $false or die "Wrong logic";
($false and $true) == $false or die "Wrong logic";
($false and $false) == $false or die "Wrong logic";
# OR
($true or $true) == $true or die "Wrong logic";
($true or $false) == $true or die "Wrong logic";
($false or $true) == $true or die "Wrong logic";
($false or $false) == $false or die "Wrong logic";
# XOR
($true xor $true) == $false or die "Wrong logic";
($true xor $false) == $true or die "Wrong logic";
($false xor $true) == $true or die "Wrong logic";
($false xor $false) == $false or die "Wrong logic";
# NOT
(not $true) == $false or die "Wrong logic";
(not $false) == $true or die "Wrong logic";
如果覺得邏輯比較複雜,建議直接用 ()
括號提升運算子優先次序,這樣程式碼會比較好讀。
指派運算子 (Assignment Operators)
除了最常用的 =
運算子之外,其他的運算子算是一種減少程式碼的語法糖。Perl 的指派運算子如下:
=
:指派值+=
:相加後指派回原變數-=
:相減後指派回原變數*=
:相乘後指派回原變數/=
:相除後指派回原變數%=
:取餘數後指派回原變數**=
:取指數後挀派回原變數
以下是實例:
my $n = 3;
$n += 4;
$ == 7 or die "Wrong value";
二元運算子 (Bitwise Operators)
二元運算子主要用於低階運算 (low-level computing) 中加速程式的一些手法,Perl 算相對高階的語言,不過仍保有二元運算的特性。以下是 Perl 的二元運算子:
&
:bitwise and|
:bitwise or^
:bitwise xor~
:bitwise not<<
:左移 (left shift)>>
:右移 (right shift)
以下是實例:
my $a = 0b0011;
my $b = 0b0101;
($a & $b) == 0b0001 or die "Wrong value";
($a | $b) == 0b0111 or die "Wrong value";
($a ^ $b) == 0b0110 or die "Wrong value";
由於 Perl 可以直接將二進位數寫出來,必要時可將數字實字寫成二進位數,相對較易讀。
二元運算其中一個用途是用來當成一種旗標 (flag),參考以下例子:
my $exec = 1; # 0001
my $write = 1 << 1; # 0010
my $read = 1 << 2; # 0100
($read ^ $write) == 6 or die "Wrong value";
($read ^ $exec) == 5 or die "Wrong value";
($read ^ $write ^ $exec) == 7 or die "Wrong value";
在此處由於我們使用二元運算,所以可以使程式碼較簡潔。
字串相關的運算子
Perl 提供以下兩種字串相關運算子:
.
:相接x
:重覆
以下是實例:
"abc" . "def" == "abcdef" or die "Wrong value";
"abc" x 3 == "abcabcabc" or die "Wrong value";
遞增 (Increment) 和遞減 (Decrement)
遞增和遞減是加減 1
的語法糖,因為我們時常在迴圈及其他情境會用到。可用的運算子如下:
++
:遞增--
:遞減
以下是實例:
my $n = 3; $n++;
$n == 4 or die "Wrong value";
遞增或遞減是表達式,但會造成變數的狀態改變,因此會有一些誤用的情形,如下例:
my $a = 3;
my $b = 4;
# DON'T DO THIS IN PRODUCTION CODE.
++$a + $b++ == 8 or die "Wrong value";
$a == 4 or die "Wrong value";
$b == 5 or die "Wrong value";
++$a + $b++
這種經典反例在很多語言都可以看到,雖然要知道這個用法,但最好不要這樣寫。
三元運算子
三元運算子是簡短版的 if ... else ...
敘述,好處是三元運算子為表達式,可以放在其他表達式中。以下是其虛擬碼:
condition ? yes : no
當 condition
的條件符合時,回傳 yes
,反之,回傳 no
。以下是實例:
my $a = 4;
my $b = 3;
my $max = $a > $b ? $a : $b;
$max == 4 or die "Wrong value";
本程式的 $a > $b ? $a : $b
會回傳兩者之中較大的值。在本例中,$a
大於 $b
,故回傳 $a
。