if 條件表達式 then elseif 條件表達式 thenendfor 控制變量, 終止變量, 步長 do enda = {}for i,v in ipairs(a) do ? endwhile i < 10 do ? ?i = i + 1 ? ?print(i)endrepeat ? ?i = 0 ? ?i = i + 1until i > 10
條件控制
true
false
邏輯控制
and
or
not
類型
function
local
nil
需要注意的點
nil == nil 是相等的
and 和 And 不同,lua 區分大小寫
lua 中條件值不僅僅只有 true 和 false
在 lua 中任何值除了 false 和 nil 都可以用作表示「真」
包括空字符串 "" 和數字 0
注釋
單行注釋 --
多行注釋 --[[]]
使多行注釋中的代碼生效 ---[[ --]]
多行注釋中包含多行注釋 --[==[ ]==]
全局變量
全局變量不需要聲明,只需要將一個值賦給它即可
lua 中可以訪問一個未初始化的變量且不會發生錯誤
但這個未初始化的變量的值為 nil
刪除全局變量賦值 nil 即可
lua 將全局變量存儲在一個普通的 table 中
解釋器
參數
-i 先執行程序塊,后進入交互模式
-e 直接執行代碼塊
-l 加載庫文件
解釋器執行參數前
會先尋找一個叫做 LUA_INIT 的環境變量
找到了,且內容為 @文件名 的話,就執行這個文件
沒找到,就假設內容為 lua 代碼, 并執行
解釋器運行腳本前
lua 將腳本前的參數存儲到 arg 這個 table 中,用作啟動參數
腳本名在這個 table 中的索引為 0,其后參數依此類推
腳本名前的參數為負數索引
lua -i -e "hello" script a b arg[0] = "script"arg[1] = "a"arg[-1] = "hello"arg[-2] = "-e"arg[-3] = "-i"
-- % 的技巧-- x % 1print(3.13 % 1) -- 得到小數部分-- x - x % 1print(3.14 - 3.14 % 1) -- 得到整數部分-- x - x % 0.1print(3.14 - 3.14 % 0.1) -- 得到整數部分 + 一位小數部分-- x - x % 0.01 以此類推,是整數部分 + 兩位小數部分
關系操作符
>
<
>=
<=
== 相等性判斷
~= 不等性判斷
邏輯操作符
and 第一個操作數為假,返回第一個,否則返回第二個
or 第一個操作數為真,返回第一個,否則返回第二個
not 只會返回 true 或 false
-- 短路操作的使用技巧print(x = x or v) -- 初始化一個值,如果 x 為 nil 沒有被初始化過,就賦值 v -- 等價于if not x then ? ?x = vend-- 實現 C 語言中的三元操作符, a ? b : cprint((a and b) or c) -- b 必須為真,才可以這樣操作-- 等價于if a == true then ? ?return belseif a == false then ? ?return cend-- 實現返回兩個數中的較大值max = (x > y) and x or y -- 因為 lua 將數字視為「真」-- 等價于if x > y then ? ?return xelse ? ?return yend
a, b = 1, 2x, y = y, x -- 交換變量a, b = 1 -- a = 1, b = nila, b = 1, 2, 3 -- a = 1, b = 2, 3 被拋棄a, b = f() -- a 接收函數 f 的第一個返回值,b 接收第二個a, b, c = 0, 0, 0 -- 初始化賦值
局部變量與塊
塊
一個塊就是程序結構的執行體,或函數的執行體
在塊內聲明的變量僅在塊內生效,即作用域為聲明它們的塊
可顯式聲明一個塊使用 do end 將要執行的內容包裹在一個塊內
局部變量
local 用來聲明一個局部變量
局部變量僅在聲明它的塊內生效,在塊的外部無效
如:在循環內部聲明在的變量在循環外部則無法使用
a = 3b = 0if a then ? ?local a = 5 ? ?b = a -- 將 then 塊內的局部變量 a ,保存到全局變量 b 中 ? ?print(a)endprint(a) -- 3print(b) -- 5do ? ?-- code blockend
盡量使用局部變量
使用局部變量要比全局變量要快
避免污染全局環境
局部變量僅在聲明它的塊中有效,即在塊外這個變量就被釋放掉了
lua 將局部變量聲明當作語句處理,即可以在任何支持書寫語句的地方書寫局部變量聲明
聲明可以包含初始化賦值
程序結構
程序結構中的條件表達式可以是任何值
條件結構
if
elseif
else
if 條件表達式 then -- 符合條件表達式執行endif 條件表達式1 then ? -- 符合條件表達式 1 執行 ? ?elseif 條件表達式2 then ? -- 符合條件表達式 2 執行endif 條件表達式 then ? ?-- 條件表達式為真時執行else ? ?-- 條件表達式為假是執行end
循環結構
for
while 條件表達式為假時退出
repeat ... until 條件表達式為真時推出,條件測試是在循環體之后做的,因此循環體至少會執行一次
在循環體內聲明的局部變量的作用域包含了條件測試
循環的三個表達式是在循環開始前一次性求值的
控制變量會被自動聲明為 for 塊中的局部變量,即作用域為 for 塊,在循環結束后不可見
不要在循環過程中修改控制變量的值
可以使用 break 或 return 在循環正常結束前提前結束它
for exp1, exp2, exp3 do ? endwhile 條件表達式 do ? endrepeat ? until 條件表達式a = 20repeat ? ?local a = 0 ? ?print(a)until a == 0 -- 可訪問在 repeat 塊內聲明的 a, 而不是全局變量 a
數值型 for
for i = 10, 0, -1 do ? ?print(i)end
泛型 for
ipairs() 用來遍歷數組
i 每次循環時都會賦予一個新的索引值,v 則是索引值所對應的元素
a = {1, 2, 3, 4, 5, 6}for i,v in ipairs(a) do ? ?print(i) ? ?print(v)endfor i,v in pairs(a) do ? ?print(i) ? ?print(v)end
兩種 for 的共同點
循環變量都是循環體的局部變量
不應該對循環遍歷進行賦值
days = {"第一天", "第二天", "第三天"}revdays = {}for i, v in ipairs(days) do ? ?revdays[v] = i -- 逆向數組,將數組索引和數組元素調換,可獲取數組元素的位置endprint(revdays["第二天"]) -- 獲取第二天所在位置?
break 和 return
break 用于結束一個循環,跳出內層循環后在外層循環中繼續執行
return 用于返回函數結果或簡單的結束函數的執行
任何函數的結尾處實際都有一句隱式的 return
如果函數無返回值,就無需在結尾處加 return
兩者的共同點
都是用作跳出當前塊
都需要放在一個塊的結尾處,即一個塊的最后一條語句
因為 return 或 break 后的語句將無法執行到
可以用 do ... end 塊包裹 return,用與調試,即調用函數但不執行函數內容的情況
a = 1if a then ? print("hello") ? break ? print("world") -- 會報錯endfor i = 1, 10 do ? ?print(i) ? ?if i > 3 then ? ? ? ?break -- 只會打印 1 2 3 4 然后就跳出循環了 ? ?endend-- 調試function foo(...) ? ?do ? ? ? return ? ?end ? ?print("執行 foo 函數") -- 不會打印endfoo(1, 2 ,3)
function foo(a, b) ? ?return a or bendfoo(1) -- a = 1, b = nilfoo(1, 2) -- a = 1, b = 2foo(1, 2, 31) -- a = 1, b = 2, 多余的 31 被拋棄-- 面向對象式調用o.foo(o, x)o:foo(x) -- 與上面的效果一樣,: 冒號操作符,隱式的將 o 作為第一個參數
多重返回值
lua 中的函數允許返回多個結果
用逗號分隔所需要返回的所有參數
string.find("you are cool", "are") -- 5 7 返回找到的字符串的開頭位置和結尾位置-- 查找數組中的最大元素,并返回這個元素的所在位置function maximum(a) ? ?local val = 1 ? ?local max = a[val] ? ?for i,v in ipairs(a) do ? ? ? ?if max < a[i] then ? ? ? ? ? ?max = a[i] ? ? ? ? ? ?val = i ? ? ? ?end ? ?end ? ?return max, valenda = {1, 2, 55, 22, 29, 4}maximum(a)
不同情況下的返回值
如果將函數作為單獨的語句執行,lua 會丟棄所有的返回值
如果將函數作為表達式的一部分調用,只保留函數的第一個返回值
只有當函數是一系列表達式中的最后一個元素(或只有一個元素的時候),才會獲取所有的返回值
一系列表達式的4種情況
多重賦值
如果一個函數調用是最后(或僅有)的一個表達式,lua 會保留盡可能多的返回值,用來匹配賦值的變量
如果一個函數沒有返回值或沒有返回足夠多的返回值,那么 lua 會用 nil 來補充缺失的值
如果一個函數調用不是一系列表達式中的最后一個元素,就只能返回一個值
function foo() endfunction foo1() return "a" endfunction foo2() return "a", "b" end?-- 第一種情況,最后(或僅有)的一個表達式x, y = foo1() -- x = a, y = b-- 第二種情況,沒有返回值x = foo() -- nil-- 第二種情況,沒有返回足夠多的返回值x, y, z = foo1() -- x = a, y = b, z = nil-- 第三種情況,不是表達式中的最后一個元素x, y = foo2(), 10 -- x = a, y = 10