語句
賦值
- 修改一個變量或者修改 table 中的一個字段的值
- 多重賦值,lua 先對等號右邊的所有元素進行求值,然後再賦值
- 值的個數小於變量的個數,那麼多餘的變量就置為 nil
- 初始化變量,應該給每一個變量賦一個初始值
- 收集函數的多個返回值
<code>x,y = y,x --變量交換a[i], a[j] = a[j], a[i]-- 值的個數小於變量的個數x, y, z = 1, 5 -- z = nilx, y = 1, 5, 8 -- x = 1, y = 5/<code>
局部變量與塊
- local 創建局部變量
- 局部變量作用域僅限於聲明他們的 塊
- 一個塊就是一個控制結構的執行體,或函數的執行體,或程序塊
<code>x = 10local i = 1while i < x do local x = i * 2 print(x) -- 2, 4, 6 ... i = i + 1endprint(x) -- 10if i > 20 then local x x = 20 print(x + 2) -- 22else print(x) -- 10 endprint(x) -- 10/<code>
交互模式將每一行理解為一個程序塊,並立即執行,可能結果會不同
顯式的界定一個塊
<code>do -- code blockend/<code>
儘量使用局部變量
- 訪問局部變量要快於全局變量
- 避免汙染全局環境
- 局部變量通常會隨這其作用域的失效而消失,便於垃圾收集器釋放
- lua 將局部變量的聲明當作語句處理,可在任何允許輸入語句的情況下,輸入局部變量的聲明
- 所聲明的局部變量的作用域從聲明語句開始直至所在塊的結束
- 聲明可包含初始化賦值
- 多重賦值時,額外的值會被丟棄,額外的變量置為 nil
- 沒有被賦值的會被置為 nil
<code>-- 習慣寫法local foo = foo -- 全局變量 foo 的值賦給局部變量 foo, 用來保存全局變量的值/<code>
控制結構
- if, elseif, for, while 顯式的終止符為 end
- repeat 顯式的終止符為 until
- 控制結構中的條件表達式可以是任何值
if
<code>if 條件表達式 then else endif a < 0 then a = 0endif a < b then return aelse return bend-- lua 不支持 switch if op == "+" then r = a + belseif op == "-" then r = a - belseif op == "*" then r = a * belseif op == "/" then r = a / belse error("invalid operation")end/<code>
while
- 測試 while 條件,如果為假,循環就結束
- 否則就執行循環體並重復這一過程
<code>local i = 1while a[i] do print(a[i]) i = i + 1end/<code>
repeat...until
- 一直執行循環體,直到條件為真時結束
<code>repeat line = io.read()until line ~= ""/<code>
- 在 lua 中一個聲明
- 在循環體中局部變量的作用域包含了條件測試
<code>-- 這在 lua 中是可以執行的local sqr = x / 2repeat sqr = (sqr + x / sqr) / 2 local error = math.abs(sqr ^ 2 - x)until error < x / 10000/<code>
數值型 for
- 變量 var 從 exp1 變化到 exp2 ,每次變化以 exp3 為步長(遞增並執行一次執行體)
- exp3 是可選的,默認為 1
<code>for var = exp1, exp2, exp3 do -- 執行體endfor i = 10, 1, -1 do print(i) -- 10, 9, 8,...end/<code>
for 的細節
- 循環的三個表達式是在循環開始前一次性求值的
- 控制變量會被自動的聲明為 for 語句的局部變量,並在循環體內可見
- 控制變量在循環結束後就不存在了
- 如果需要在循環結束後訪問控制變量,必須將控制變量的值保存在另一個變量中
- 不要在循環過程中修改控制變量的值
- 可使用 break 語句在 for 正常結束前提前結束它
泛型 for
- 通過迭代器函數遍歷所有的值
- ipairs() 用來遍歷數組
- 在每次循環中 i 都會被賦予一個新的索引值,v 會被賦予一個對應於該索引的元素值
<code>for i,v in ipairs(a) do print(v)end-- 打印 table 中的 key 值for k, in pairs(t) do print(k) end/<code>
二種 for 類型的共同點
- 循環變量都是循環體的局部變量
- 不應該對循環變量進行賦值
<code>days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}-- 將名稱轉換成它在一週中的位置,索引為字符串,值為對應的位置,方便查找,逆向 tablerevDays = {["Sunday"] = 1, ["Monday"] = 2 ,["Tuesday"] = 3, ["Wednesday"] = 4, ["Thursday"] = 5, ["Friday"] = 6, ["Saturday"] = 7}x = "Tuesday"print(revDays[x]) -- 3 打印 Tuesday 的位置revDays = {}for k,v in pairs(days) do revDays[v] = kend/<code>
break 與 return
- 都用於跳出當前塊
- break 用於結束一個循環,只會跳出包含它的內層循環,而不會跳出外層循環
- 執行 break 後,會在跳出的外層循環中繼續執行
- return 用於函數返回結果或簡單的結束函數的執行
- 任何函數的結尾處實際上都有一句隱式的 return
- 如果函數沒有值需要返回的話,需要在其結尾處添加 return 語句
- break 和 return 只能是一個塊的最後一條語句(應該是程序塊的最後一條語句如:end, else, until 前的一條語句)
- 因為 return 或 break 後的語句將無法執行到
<code>local i = 1while a[i] do if a[i] == v then break -- 條件語句塊中的最後一條語句 endi = i + 1end/<code>
閱讀更多 有所得 的文章