# 控制結構:for
Lua提供了一組傳統的、小巧的控制結構,包括用于條件判斷的if、用于迭代的while、repeat和for。本章節主要介紹for的使用。
#### 數字型for
for語句有兩種形式:數字for(numeric for)和范型for(generic for)。
> 數字型for的語法如下:
`for var = exp1, exp2, exp3 do`
var從exp1變化到exp2,每次變化都以exp3作為步長(step)遞增var,并執行一次“執行體”。第三個表達式exp3是可選的,若不指定的話,Lua會將步長默認為1。
> 示例
~~~
for i=1,5 do
print(i)
end
-- output:
1
2
3
4
5
~~~
...
~~~
for i=1,10,2 do
print(i)
end
-- output:
1
3
5
7
9
~~~
> 以下是這種循環的一個典型示例:
~~~
for i=10, 1, -1 do
print(i)
end
-- output:
...
~~~
如果不想給循環設置上限的話,可以使用常量math.huge:
~~~
for i=1, math.huge do
if (0.3*i^3 - 20*i^2 - 500 >=0) then
print(i)
break
end
end
~~~
#### 泛型for
泛型for循環通過一個迭代器(iterator)函數來遍歷所有值:
~~~
-- 打印數組a的所有值
local a = {"a", "b", "c", "d"}
for i, v in ipairs(a) do
print("index:", i, " value:", v)
end
-- output:
index: 1 value: a
index: 2 value: b
index: 3 value: c
index: 4 value: d
~~~
Lua的基礎庫提供了ipairs,這是一個用于遍歷數組的迭代器函數。在每次循環中,i會被賦予一個索引值,同時v被賦予一個對應于該索引的數組元素值。
> 下面是另一個類似的示例,演示了如何遍歷一個table中所有的key
~~~
-- 打印table t中所有的key
for k in pairs(t) do
print(k)
end
~~~
從外觀上看泛型for比較簡單,但其實它是非常強大的。通過不同的迭代器,幾乎可以遍歷所有的東西,而且寫出的代碼極具可讀性。標準庫提供了幾種迭代器,包括用于迭代文件中每行的(io.lines)、迭代table元素的(pairs)、迭代數組元素的(ipairs)、迭代字符串中單詞的(string.gmatch)等。
泛型for循環與數字型for循環有兩個相同點:(1)**循環變量是循環體的局部變量**;(2)**決不應該對循環變量作任何賦值**。對于泛型for的使用,再來看一個更具體的示例。假設有這樣一個table,它的內容是一周中每天的名稱:
~~~
local days = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
}
~~~
現在要將一個名稱轉換成它在一周中的位置。為此,需要根據給定的名稱來搜索這個table。然而在Lua中,通常更有效的方法是創建一個“逆向table”。例如這個逆向table叫revDays,它以一周中每天的名稱作為索引,位置數字作為值:
~~~
local revDays = {
["Sunday"] = 1,
["Monday"] = 2,
["Tuesday"] = 3,
["Wednesday"] = 4,
["Thursday"] = 5,
["Friday"] = 6,
["Saturday"] = 7
}
~~~
接下來,要找出一個名稱所對應的需要,只需用名字來索引這個reverse table即可:
~~~
local x = "Tuesday"
print(revDays[x]) -->3
~~~
當然,不必手動聲明這個逆向table,而是通過原來的table自動地構造出這個逆向table:
~~~
local days = {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"
}
local revDays = {}
for k, v in pairs(days) do
revDays[v] = k
end
-- print value
for k,v in pairs(revDays) do
print("k:", k, " v:", v)
end
-- output:
k: Tuesday v: 2
k: Monday v: 1
k: Sunday v: 7
k: Thursday v: 4
k: Friday v: 5
k: Wednesday v: 3
k: Saturday v: 6
~~~
這個循環會為每個元素進行賦值,其中變量k為key(1、2、...),變量v為value("Sunday"、"Monday"、...)。
- 序
- Lua簡介
- Lua環境搭建
- 基礎數據類型
- 表達式
- 控制結構
- if/else
- while
- repeat
- 控制結構for的使用
- break,return
- Lua函數
- 函數的定義
- 函數的參數
- 函數的返回值
- 函數回調
- 模塊
- String庫
- Table庫
- 日期時間函數
- 數學庫函數
- 文件操作
- 元表
- 面向對象編程
- FFI
- LuaRestyRedisLibrary
- select+set_keepalive組合操作引起的數據讀寫錯誤
- redis接口的二次封裝(簡化建連、拆連等細節)
- redis接口的二次封裝(發布訂閱)
- pipeline壓縮請求數量
- script壓縮復雜請求
- LuaCjsonLibrary
- json解析的異常捕獲
- 稀疏數組
- 空table編碼為array還是object
- 跨平臺的庫選擇
- PostgresNginxModule
- 調用方式簡介
- 不支持事務
- 超時
- 健康監測
- SQL注入
- LuaNginxModule
- 執行階段概念
- 正確的記錄日志
- 熱裝載代碼
- 阻塞操作
- 緩存
- sleep
- 定時任務
- 禁止某些終端訪問
- 請求返回后繼續執行
- 調試
- 調用其他C函數動態庫
- 我的lua代碼需要調優么
- 變量的共享范圍
- 動態限速
- shared.dict 非隊列性質
- 如何添加自己的lua api
- 正確使用長鏈接
- 如何引用第三方resty庫
- 使用動態DNS來完成HTTP請求
- 緩存失效風暴
- Lua
- 下標從1開始
- 局部變量
- 判斷數組大小
- 非空判斷
- 正則表達式
- 不用標準庫
- 虛變量
- 函數在調用代碼前定義
- 抵制使用module()函數來定義Lua模塊
- 點號與冒號操作符的區別
- 測試
- 單元測試
- API測試
- 性能測試
- 持續集成
- 灰度發布
- web服務
- API的設計
- 數據合法性檢測
- 協議無痛升級
- 代碼規范
- 連接池
- c10k編程
- TIME_WAIT問題
- 與Docker使用的網絡瓶頸
- 火焰圖
- 什么時候使用
- 顯示的是什么
- 如何安裝火焰圖生成工具
- 如何定位問題