[Lua] 程式設計教學:使用控制流程 (Control Structure)

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    前言

    在預設情形下,程式碼由上往下依序執行。控制結構 (control structure) 用於改變程式進行的順序,可分為兩類:

    • 選擇 (selection):僅執行符合條件的區塊
    • 迭代 (iteration):反覆執行某區塊

    本文介紹 Lua 可用的控制結構。

    if

    if 是選擇性執行特定區塊的方式,只有在符合條件時才會執行該區塊。以下為 if 虛擬碼:

    if condition then
      -- Run code here if `condition` is true
    end
    

    condition 為真時,執行 if 區塊內的程式碼,然後離開整個 if 敘述。

    我們也可以加上反向的 else 敘述,參考以下虛擬碼:

    if condition then
      -- Run code here if `condition` is true
    else
      -- Run code here if `condition` is not true
    end
    

    condition 為真,則執行 if 區塊內的程式碼;反之,則執行 else 區塊內的程式碼。

    除了二元敘述外,也可以加上多個 elseif 區塊,形成多元敘述,參考以下虛擬碼:

    if condition 1 then
      -- code block 1
    elseif condition 2 then
      -- code block 2
    else
      -- code block 3
    end
    

    註:Lua 的 elseif 是單一保留字,在 else 及 if 間沒有空格。

    在以上虛擬碼中,共有三塊程式碼區塊,若符合 condition 1,則會進入 code block 1,執行完該區塊後就跳出整個 if 敘述;若不符合 condition 1,接著會判斷 condition 2,若符合,則執行 code block 2;若前述條件皆不符合,則執行 else 內的 code block 3

    以下為實例:

    local a = 0
    
    if a > 0 then
      print("a is larger than zero")
    elseif a < 0 then
      print("a is smaller than zero")
    else
      print("a is equal to zero")
    end

    在本例中,先前的條件皆不符合,故僅執行 else 區塊內的程式碼。

    while

    while 是以條件句為終止條件的迴圈,會反覆執行某區塊,直到條件不符時,才會跳出 while 敘述。while 寫成虛擬碼如下:

    while condition do
      -- Run code here repeatedly while `condition` is true
    end
    

    以下是實例:

    local i = 1
    
    while i <= 10 do
      print(i)
      i = i + 1
    end

    以下的 while 迴圈是無限迴圈:

    while true do
      -- Do something here.
    end

    有時候無限迴圈是不小心造成的 bug,但也可能是刻意安排的。實務上,我們會用一些條件在適當的時機終止無限迴圈,詳見後文。

    repeat

    repeat ... untilwhile 語義相反,反覆執行某區塊,直到某個條件成立為止。寫成虛擬碼如下:

    repeat
      -- Run code here repeatedly until `condition` is true
    until condition
    

    以下是實例:

    local i = 1
    
    repeat
      print(i)
      i = i + 1
    until i > 10

    由於 repeatwhile 語義上可代換,但 repeat 的語義是負向的,故少用;通常是使用 while 敘述為主,僅在語義上剛好符合 repeat 時才會使用。

    for

    for 敘述有兩種,一種使用計數器 (counter),另一種使用迭代器 (iterator)。

    使用計數器

    for 適用於有特定次數的迭代。如以下實例:

    for i = 1, 10 do
      print(i)
    end

    本例會迭代 10 次,從 110

    不一定要以 1 計數,也可以用別的數字,實例如下:

    for i = 10, 1, -2 do
      print(i)
    end

    本例會迭代 5 次,從 102

    使用迭代器

    透過迭代器 (iterator),我們可以在不知道容器 (collection) 內部實作的前提下走訪容器。我們將於講解表 (table) 時再一併介紹迭代器。

    break

    break 需搭配迴圈使用,用於提早離開迴圈,實例如下:

    local i = 1
    
    while i <= 10 do
      if i > 5 then
        break
      end
      
      print(i)
      i = i + 1
    end

    return

    return 用於離開函式並回傳值,我們將於講解函式時介紹。

    goto

    註:goto 僅在 Lua 5.2 版後才支援。

    使用 goto 搭配標籤可以任意跳躍位置,不過,會受到可視度 (scope) 的限制。在 Lua 中使用 goto 通常是為了模擬別的語言的 continue,實例如下:

    for i = 1, 10 do
      if i % 2 ~= 0 then
        goto continue
      end
      
      print(i)
      
      ::continue::
    end

    如果使用 Lua 5.1 版,則要使用額外的旗標 (flag) 去達成相同的行為,如以下實例:

    for i = 1, 10 do
      local flag = true
    
      if i % 2 ~= 0 then
        flag = false
      end
      
      if flag then
        print(i)
      end
    end

    Lua 沒有 continue

    這和大部分的主流語言相異,一開始會不太習慣。目前 Lua 開發團隊似乎沒有要加上 continue 的跡象,現階段只能用其他的語法去模擬。Lua 官網有相關的討論,有興趣的讀者可以看一看。

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