Lua Manual 閱讀筆記
- 關鍵字:
and break do else elseif end false for function if in local nil not or repeat return then true until while
> print(_VERSION) Lua 5.1
- tokens:
+ - * / % ^ # == ~= <= >= < > = () {} [] ; : , . .. ...
-
字串可以以單引號或者雙引號包圍,中間可以包含c風格的轉義字串如
\t
等.-
\a
響鈴 -
\b
空格 -
\f
form feed -
\n
新的一行 -
\r
回車 -
\t
橫向tab -
\v
縱向tab -
\\
\
本身 -
\"
雙引號本身 -
\'
單引號本身 - \ 加 回車代表字串裡新的一行
-
-
不轉義字元可以用
[[
的兩個[
中間加上n個=
來表示, 0個就是0級, n個就是 n級. 如果開括號後直接跟一個換行符, 則忽略這個換行符:
> print('hello\n123') hello 123 > print([[hello >> 123]]) hello 123 > print([[ >> hello >> 123]]) hello 123
-
字串也可以用
\
加上其ascii值來表示, 十進位制,最多三位. 如\97
-
--
開頭的是註釋, 後面可以接雙括號, 不過我還是喜歡每行--
因為vim幫我幹了. -
lua中的值有八種類型:
- nil
- boolean
- number
- string
- function
- userdata 用來儲存裸的記憶體塊,只能通過c API來操作,不能在lua中直接操作
-
thread 協程中的"執行緒"的概念,相當於Golang中的
G
-
table 是lua中的一個數據結構,既可以當陣列用,又可以當雜湊表用,還有
a.name
語法糖,相當於a["name"]
type
函式返回資料的型別:
> print(type(1)) number > print(type("hello")) string
- lua會在操作字串和數字的時候自動進行型別轉換,例如:
> print(1 + "2") 3
坑啊...和js一樣...我很討厭這種特性.
-
Lua有三種變數
- 全域性變數
- 本地變數
- table項(table fields)
以var ::= Name
的形式賦值給變數, 預設全域性變數, 除非加了local
關鍵字,
本地變數可以被其作用域內的函式訪問到. 第一次賦值前, 變數的預設值為nil
.
全域性變數儲存在_env
裡.
預設全域性變數,又是一個坑.
- 賦值, 賦值的時候, 如果右邊比左邊長, 則多餘的值會被丟掉. 相反, 則用nil填充. 賦值語句首先計算出所有變數,然後才進行賦值,例如:
i = 3 i, a[i] = i+1, 20
執行完之後,a[3]
的值是20,a[4]
不受影響.
-
false
和nil
是false,其他的都是true, 所以0和空字串也是true. -
for有兩種形式, 一種像c:
local i = 0 for i = 0, 10, 2 do print(i) end
$ luajit test.lua 0 2 4 6 8 10
只能用來做算術迴圈.
另一種像 Python:
local names = {"hello", "world"} for k, v in ipairs(names) do print(k, v) end
$ luajit test.lua 1hello 2world
-
函式和變長引數都可以產生多值. 如果作為表示式, 那麼結果會被忽略, 例如函式
呼叫
f()
那麼其結果會被忽略. 如果作為表示式的非最後一個元素, 那麼多值結果會被 省略,只剩下第一個, 如果作為最後一個元素,那麼就會保留所有結果.
function f() return 1, 2, 3 end local a local b local c f() print(a, b, c) a, b, c = f(), 4, 5 print(a, b, c) a, b, c = f() print(a, b, c) a, b, c = 9, 8, f() print(a, b, c)
$ luajit t.lua nil nil nil 145 123 981
-
== ~= < > <= >=
總是產生布爾值. 數字和字串比較值,物件(tables, userdata, threads, functions)比較引用值. -
and, or, not
其中and
和or
支援條件短路. 所以如果第一個引數是false
或者nil
就返回第一個引數,否則返回第二個引數. -
..
連線字串
> print("hello" .. 1) hello1
-
length. 通過
#
號取出長度, 對字串來說是bytes的個數,對table來說,是最後一個 非空值的index. 例如a[1], a[2], a[3]
為1, 而a[4]
為nil,a[5]
為2, 那麼 長度為3.
local a = {1, 2, 3, nil, 4} print(#a)
$ luajit t.lua 3
坑啊,table支援空洞額...
-
每次遇到local關鍵字,都會新建一個變數。如果在for迴圈裡local的話,就會新建 迴圈次數個變數。
-
metatables
lua中每個值都有metatable,其中的key稱為events,值稱為metamethods. 每個events
的名字都是兩個下劃線開頭,例如__add
。主要包括以下方法:
- add + - sub - - mul * - div / - mod % - pow ^ - unm -負號 - concat .. 字元連線號 - len # 號 - eq `==` - lt < - le <= - index `table[key]` - newindex `table[key] = value` - call
此外,thread,function和userdata這三種類型的物件還有一個table與之相關,叫做 encironment。thread的環境變數在thread內共享,userdata和c函式在c函式內共享。 非巢狀lua函式和建立的thread共享,巢狀的lua函式和巢狀的lua函式共享。
lua thread級別的envrionment table就是全域性變數。可以通過getfenv
和setfenv
獲取和修改。
-
coroutine 內建coroutine算是lua的一個特色了
coroutine.create coroutine.resume coroutine.yield coroutine.wrap
local newThread = coroutine.wrap(function() print("hello") local a = coroutine.yield() print(a) end) newThread() newThread("haha")