控制結構教學

lua-users home
wiki

控制結構讓你的程式做出選擇,或者是多次執行相同的程式碼。

if 語句

if 語句讓你依據一個條件來執行不同的程式碼

if condition then
  block
elseif condition2 then
  block
elseif condition3 then
  block
else
  block
end

會依序檢查 ifelseif 部分,一旦其中一個條件為真,便執行其下方的區塊,並跳到最後,略過後面的 elseif 條件。如果沒有一個條件符合,則執行 else 區塊。最後,elseifelse 部分為選用。

> n = 5
> if n > 5 then print("greater than 5") else print("less than 5") end
less than 5
> n = 7
> if n > 5 then print("greater than 5") else print("less than 5") end
greater than 5

一個更複雜的範例

> n = 12
> if n > 15 then
>> print("the number is > 15")
>> elseif n > 10 then
>> print("the number is > 10")
>> elseif n > 5 then
>> print("the number is > 5")
>> else
>> print("the number is <= 5")
>> end
the number is > 10

請注意,即使多個條件為真,只會列印其中一個訊息:這是因為一旦有一個條件符合,if 語句便會略過檢查其餘條件。

while 迴圈

while condition do
  block
end

這會在迴圈中不斷執行區塊,但每次反覆之前,它會先檢查條件,如果為假,便會跳到 end,終止迴圈。如果條件始終為假,則永遠不會執行區塊。

> i = 1
> while i <= 10 do
>> print(i)
>> i = i + 1
>> end
1
2
3
4
5
6
7
8
9
10

repeat 迴圈

repeat
  block
until condition

while 迴圈相同,不過條件相反(為真時會終止迴圈),且在第一次反覆後檢查條件,因此程式碼保證至少會執行一次。

> i = 5
> repeat
>> print(i)
>> i = i - 1
>> until i == 0
5
4
3
2
1

數字 for 迴圈

for variable = start, stop, step do
  block
end

變數 起初等於 開始 之後執行區塊,然後持續增加 步驟 數量,並再次執行區塊,直到它大於 停止步驟 可以省略,預設為 1。

你也可以讓步驟為負數,迴圈將在計數器變數小於停止值時停止。

> for i = 1, 5 do
>> print(i)
>> end
1
2
3
4
5
> for i = 1, 100, 8 do
>> print(i)
>> end
1
9
17
25
33
41
49
57
65
73
81
89
97
> for i = 3, -3, -1 do
>> print(i)
>> end
3
2
1
0
-1
-2
-3
> for i = 0, 1, 0.25 do
>> print(i)
>> end
0
0.25
0.5
0.75
1
> for i = 1, 3 do
>> for j = 1, i do
>> print(j)
>> end
>> end
1
1
2
1
2
3

另外請記住,for 迴圈中的變數只會在區塊內可見,迴圈終止後它不會仍然包含最後一個值。

迭代器 for 迴圈

for var1, var2, var3 in iterator do
  block
end

迭代器版本的 for 迴圈採用一個特殊的迭代器函式,並且可以有多個變數。迴圈的作用、需要的變數數量和它們會設定為什麼值,都取決於迭代器。

這主要適用於表格(尚未介紹),這裡提供一個範例讓你了解這個概念

> tbl = {"a", "b", "c"}
> for key, value in ipairs(tbl) do
>> print(key, value)
>> end
1       a
2       b
3       c

在此,ipairs 就是迭代器,依序取得表格中的編號式紀錄。

break 語句

break 語句會導致 Lua 跳出目前的迴圈

> i = 3
> while true do -- infinite loop
>> print(i)
>> i = i + 1
>> if i > 6 then
>> break
>> end
>> end
3
4
5
6

對於巢狀迴圈,break 只會影響最裡面的迴圈

> for i = 1, 2 do
>> while true do
>> break
>> end
>> print(i)
>> end
1
2

在迴圈之外使用 break 會是語法錯誤

> break
stdin:1: <break> at line 1 not inside a loop

continue 語句替代方案

許多其他語言都有 continue 語句,可以略過最裡面迴圈中的目前反覆的剩餘部分。在 Lua 5.2 中,可以使用 goto 來模仿這個功能

> for i = 1, 10 do
>> if i>3 and i<6 then goto continue end
>> print(i)
>> ::continue:: -- a name surrounded in :: :: is a goto label
>> end
1
2
3
6
7
8
9
10

Lua 5.1 與之前版本沒有 goto,但有其他變通方法

> for i = 1, 10 do
>> if not (i>3 and i<6) then
>> print(i)
>> end
>> end
1
2
3
6
7
8
9
10
> for i = 1, 10 do repeat
>> if i>3 and i<6 then break end
>> print(i)
>> until true end
1
2
3
6
7
8
9
10

條件

條件不一定是布林值。事實上,任何值都是有效的條件:nilfalse 會使條件為假,其他任何東西(包括 0)都會使它為真。

> if 5 then print("true") else print("false") end
true
> if 0 then print("true") else print("false") end
true
> if true then print("true") else print("false") end
true
> if {} then print("true") else print("false") end
true
> if "string" then print("true") else print("false") end
true
> if nil then print("true") else print("false") end
false
> if false then print("true") else print("false") end
false

也有一些語言中,變量賦值被認為是一種表達式(因此可以將其用作子表達式),因此以下這類程式碼是對的

> i = 0
> while (i = i + 1) <= 10 do print(i) end
stdin:1: ')' expected near '='
但在 Lua 中,賦值是一種語句,上面的範例會發生語法錯誤。

if/else 作為表達式

有些語言有一個三元運算式,它就像一個 if/else 語句,但可以用作子表達式。如果條件為真,它就會評估為一個表達式,否則它就會評估另一個表達式。

Lua 沒有這樣的運算式,但在許多情況下,你可以使用 and 和 or 邏輯運算子來模仿它。這樣做的原因有兩個:如果僅從左側結果就能得知邏輯結果,這些運算子甚至不會運行右側表達式;另外它們會直接傳回其子表達式的結果,而不是將其轉換為布林值。

> = true and print("test")
test
nil
> = false and print("test") -- 'and' is always false if one of the sides are false, don't bother running the other expression
false
> = true or print("test") -- 'or' is always true if one of the sides are true, don't bother running the other expression
true
> = false or print("test")
test
nil
> = 8 or 5
8
> = true and "text"
text

這可用於建立一個簡單的 if/else 表達式

> condition = true
> = condition and 2 or 4
2
> condition = false
> = condition and 2 or 4
4
> = condition and print("a") or print("b") -- only the "false" branch is run, otherwise both a and b would be printed
b
nil

請記住,「and」的優先順序高於「or」:如果條件為假,它會讓「and」表達式放棄並傳回 false。這會讓「or」部分嘗試它的右側表達式並傳回其值。如果條件為真,「and」會傳回它的右側表達式。然後這個結果會給「or」,它會看到左側結果是一個真條件,然後傳回它。

請注意,我們假設真分支的結果是一個作為真條件的值。這會導致一個陷阱:真分支不能評估為 nilfalse,因為這樣假分支也會執行,而且它的值也會傳回。

> condition = true
> = condition and false or true -- wrong result!
true

這是因為整個「and」子表達式現在為假,導致「or」嘗試執行其另一個子表達式。不過從假分支傳回一個假值是沒問題的。事實上,如果你遇到像上面範例那樣的情況,你可以反轉條件並交換分支的內容。

> condition = true
> = not condition and true or false
false

如果兩個分支都必須傳回作為假條件的值,則有一種方法可以使用「or true」運算子。

> condition = 1
> =condition >= 1 and (print("condition >= 1") or true) or print("condition < 1")
condition >= 1
true

RecentChanges · 偏好設定
編輯 · 歷程
最後編輯時間:2023 年 6 月 5 日 下午 12:03 GMT (diff)