使用運算子 (Operator)

    前言

    運算子 (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";
    

    在這些運算子中,<=> 可以同時判定大於、等於、小於三種情境,會分別回傳 10-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 沒有真正的真偽值,故我們在範例中分別將 10 做為 $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

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Yahoo
    【追蹤本站】
    Facebook Facebook Twitter Plurk