前言
在預設情形下,程式碼由上往下依序執行。控制結構 (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 ... until
和 while
語義相反,反覆執行某區塊,直到某個條件成立為止。寫成虛擬碼如下:
repeat
-- Run code here repeatedly until `condition` is true
until condition
以下是實例:
local i = 1
repeat
print(i)
i = i + 1
until i > 10
由於 repeat
和 while
語義上可代換,但 repeat
的語義是負向的,故少用;通常是使用 while
敘述為主,僅在語義上剛好符合 repeat
時才會使用。
for
for
敘述有兩種,一種使用計數器 (counter),另一種使用迭代器 (iterator)。
使用計數器
for
適用於有特定次數的迭代。如以下實例:
for i = 1, 10 do
print(i)
end
本例會迭代 10 次,從 1
到 10
。
不一定要以 1 計數,也可以用別的數字,實例如下:
for i = 10, 1, -2 do
print(i)
end
本例會迭代 5 次,從 10
到 2
。
使用迭代器
透過迭代器 (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 官網有相關的討論,有興趣的讀者可以看一看。