選擇控制結構 (Selection Control Structures)

    前言

    控制結構 (control structures) 用來調整程式行進的方向,幾乎每個高階程式語言都會有這些特性。控制結構分為 (1) 選擇 (selection) 和 (2) 迭代 (iteration) 兩種。本文介紹 Perl 之中和選擇相關的控制結構。

    真值和偽值

    Perl 沒有真正的真值 (true value) 和偽值 (false value),程式內部會自動判定值的真偽。以下值認定為偽 (falsy):

    • undef:未定義的值
    • 0:數字零 (zero)
    • "":空字串
    • "0":僅包含零的字串
    • 空陣列
    • 空雜湊

    其他的值視為真 (truely)。

    if

    if 依據給定的條件決定是否要執行特定程式碼區塊 (block)。以下是 if 的虛擬碼:

    if (cond) {
        # Run code here if `cond` is true.
    }
    

    只有當 cond 為真時才會執行該程式碼區塊。

    if 還可以 (選擇性) 搭配反向的 else 敘述,形成二元敘述。其虛擬碼如下:

    if (cond) {
        # Run code here if `cond` is true.
    } else {
        # Run code here if `cond` is not true.
    }
    

    cond 為真時,就執行 if 區塊內的敘述。反之,則執行 else 區塊內的敘述。

    除了使用 else 外,還可以搭配一到多個 elsif 形成多元敘述。其虛擬碼如下:

    if (condition_a) {
        # Do something a
    } elsif (condition_b) {
        # Do something b
    } else {
        # Do something else
    }
    

    這裡面有三個區塊,若符合 ifcondition_a 條件,會執行 something a 所在的程式碼,之後跳離這個敘述。若不符合 condition_a,會判斷 elsif 區塊的 condition_b 條件,若符合該條件,則執行 something b 所在的程式碼,之後跳離這個敘述。若先前的條件皆不符合,則會執行 else 區塊內的程式碼後離開此敘述。

    if 敘述中,只有 if 區塊是必備的,elsifelse 區塊都是選擇性的。elsif 區塊可以重覆出現多次,而 else 區塊只能出現一次,且要放在 if 敘述的最尾端。這些規則用語義去想即可,不要死背。

    以下是 if 敘述的實例:

    my $n = int(rand(10)) + 1;
    
    if ($n % 5 == 0) {
        print "$n is divisible by 5\n";
    } elsif ($n % 3 == 0) {
        print "$n is divisible by 3\n";
    } elsif ($n % 2 == 0) {
        print "$n is divisible by 2\n";
    } else {
        print "\$n is $n\n";
    }
    

    rand() 函式會回傳一個介於 01 之間的浮點數,而 rand(10) 會回傳一個介於 010 之間的浮點數。int() 函式會將傳入的浮點數去掉小數後的部分。以本例來說,int(rand(10)) + 1 會得到一個介於 110 之間的整數。

    接著,根據 $n 的值印出不同的訊息。由於 if 在判斷條件上有先後順序,故我們將除數由大至小排列。

    unless

    unless 用法和 if 相同,而語義則相反。由於 unless 本身隱含著否定的意味,在複合條件句上會比較難寫,除非語意適合,一般建議用 if 加上否定條件,在程式碼上較易於理解。以下是 unless 的實例:

    my $n = int(rand(10)) + 1;
    
    unless ($n % 2 != 0) {
        print "$n is even\n";
    } else {
        print "$n is odd\n";
    }
    

    given

    given 是 Perl 5.10 版後加入的新語法,主要用來提供類似 C 家族語言的 switch,算是 if 的語法糖。以下是一個短例:

    use feature "switch";
    
    my $day = (localtime)[6];
    
    given ($day) {
        when ((0, 6)) {
            print "Weekend\n";
        }
        when (5) {
            print "Thank God. It's Friday.\n";
        }
        when (3) {
            print "Hump day\n";
        }
        default {
            print "Week";
        }
    }
    

    由於 given 是一個新的語法,我們要額外使用 use feature "switch"; 開啟這項特性,而且 Perl 的版本不能太舊。5.10 是西元 2007 年時發佈的,現在大部分機器上的 Perl 版本都比較個版本還新。

    localtime() 函式會得到一個代表時間的串列,其中的第七項數值就代表該週的某一天 (the day of a week)。我們將該數值取出,並存入 $day 變數。

    接著,在 given 區塊中判斷 $day 的值,並給予相對應的動作。在 given 區塊中,每個 when 區塊會對應一個值,若符合特定值,則執行該區塊,然後離開 given 敘述。若所有 when 條件都不符合而 default 區塊存在時,則執行 default 區塊。default 區塊是選擇性的,不加也可行。

    在本例的第一個 when 敘述中,我們放入一個串列 (0, 6),只要 $day 符合該串列其中一個值,即會執行該區塊內的動作。我們會在後續的文章介紹串列。

    後位修飾 (Postfix Modifier)

    後位修飾是一種控制結構的變形語法,可用在 ifunlessforwhileuntil 等,主要的用意是讓程式碼變簡潔。後位修飾常用於 Perl one liner,在一般命令稿中相對少用。以下是實例:

    my $n = int(rand(10)) + 1;
    
    print "$n is even\n" if $n % 2 == 0;
    
    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Yahoo
    【追蹤本站】
    Facebook Facebook Twitter Parler