教學指南

lua-users home
wiki

for 語句有兩種不同的形式。一可用於遍歷數值進程,另一可用於遍歷稱為「迭代器」的函數。參考手冊的 2.4.5 部分中涵蓋了 for 語句。[1]

數值進程

數值進程版本的 for 採用以下語法

for variable = from_exp , to_exp [, step_exp] do block end

此語句會在進入 for 區塊前將 variable 的值設定為 from_exp。僅在 variable 未超過最後一個值 to_exp 時才會進入區塊。這包含第一遍遍歷迴圈時。區塊每次結束時,會將 step_exp 加到 variable 中。指定步驟表示式為選用。如果未指定,則使用 1。例如:

> for i = 1,3 do print(i) end     -- count from 1 to 3
1
2
3
> for i = 3,1 do print(i) end -- count from 3 to 1 in steps of 1. zero iterations!
> for i = 3,1,-1 do print(i) end  -- count down from 3 to 1
3
2
1
> for i=1,0,-0.25 do print(i) end -- we're not limited to integers
1
0.75
0.5
0.25
0
請注意,變數 i 會是 for 迴圈作用範圍內的區域變數,也就是說:
> print(i) -- after the above code
nil

for v = e1, e2, e3 do block end 等於以下 Lua 程式碼

do
  local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
  if not (var and limit and step) then error() end
  while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
    local v = var
    block
    var = var + step
  end
end

迭代器

for 迴圈的第二種形式採用語法:

for var {, var} in explist do block end

explist 在進入迴圈前先評估一次。其結果是一個 iterator function(用於設定 var 值)、一個 state(可從其中讀取值)及一個 initial value(用於繼續遍歷)。

pairs(table)

Lua 提供一個 pairs() 函數,為我們建立 explist 資訊以便遍歷表格。pairs() 函數允許遍歷 key-value 對。請注意,返回項目順序未定義,即使是索引表格也不例外。

> for key,value in pairs(t) do print(key,value) end
3       10
1       3
4       17
2       7
pi      3.14159
banana  yellow

ipairs(table)

ipairs() 函數允許遍歷 index-value 對。這些是「key-value」對,其中鍵是陣列中的索引。保證以索引的數值順序返回元素順序,而非整數鍵會直接跳過。使用與上例中相同的表格:

> for index,value in ipairs(t) do print(index,value) end
1       3
2       7
3       10
4       17
請注意,因為僅有這些元素有索引鍵,所以只顯示表格中陣列的部分。

next()

next(table [,index]) 函數協助遍歷表格。當提供表格和索引時,它會從表格中返回下一組 key-value 對,例如:

> = next(t) -- index will be nil, the beginning
1       3
> = next(t,4)
pi      3.14159

pairs() 一樣,返回項目的順序並未定義;索引鍵可以任何順序返回,而不僅是數值遞增。pairs() 函數會傳回包含有 next()explist,因此我們可以遍歷表格。我們可以將自己的表示式清單傳遞給 for 語句,如下所示:

> for key,value in next,t,nil do print(key,value) end
1       3
2       7
3       10
4       17
pi      3.14159
banana  yellow
我們傳遞 next,table,nil 作為表達式清單到 for 陳述式。我們在這裡表示我們要使用迭代器函式 `next()`,在表 t,從 nil (開頭) 開始。for 陳述式會持續執行直到 next() 函式傳回 nil (表的結尾)。

io.lines()

Lua 提供其他實用迭代器,像在 io 函式庫中的 io.lines([filename])。我們可以透過建立一個自訂檔包含幾行文字來示範這個。

> io.output(io.open("my.txt","w"))
> io.write("This is\nsome sample text\nfor Lua.")
> io.close()
我們建立一個稱為 "my.txt" 的檔案,寫三行到該檔案然後關閉它。現在我們可以透過 io.lines 迭代器來讀取它
> for line in io.lines("my.txt") do print(line) end
This is
some sample text
for Lua.

file:lines()

io 函式庫提供另一種方法來反覆處理文字檔的行。

> file = assert(io.open("my.txt", "r"))
> for line in file:lines() do print(line) end
This is
some sample text
for Lua.
> file:close()

io.lines() 有哪些差異?

您必須明確開啟並關閉檔案。此優點之一是,如果無法開啟檔案,您可以好好處理此失敗。在此,assertio.lines 有相同效果:直譯器會停止並顯示指向有問題行的錯誤訊息;但您可以測試 filenil 值並執行其他動作。

另一個優點是,您可以從任何行開始迴圈

file = assert(io.open("list.txt", "r"))
local line = file:read()
if string.sub(line, 1, 1) ~= '#' then
  ProcessLine(line) -- File doesn't start with a comment, process the first line
end
-- We could also loop on the first lines, while they are comment
-- Process the remainder of the file
for line in file:lines() do
  ProcessLine(line)
end
file:close()

自訂迭代器

我們可以撰寫自己的迭代器,類似於 next(),以反覆處理任何資料序列。這在 IteratorsTutorial 中有更詳細的說明。


RecentChanges · 偏好設定
編輯 · 記錄
上次編輯於 2017 年 7 月 14 日 下午 12:51 GMT (差異)