Lua值與型別深入理解
值
在Lua中,只有值有型別,變數不需要定義型別;
local a -- 無需定義型別
print(type(a)) -- nil 變數沒有型別
print(type(10)) -- number 只有值有型別
而在C#中,值和變數都有型別。
int b; //變數要指明型別
Console.WriteLine(b.GetType()); // System.Int32
Lua中所有值都是first-class
:任何型別(包括function)的值都可賦值給一個變數,也可當作引數傳遞給另一個function,也可當作返回值被函式返回。
local function f1() print("f1") end local function f2(f) f() return function () print("f2") end end f2(f1)()
型別
Lua中有8種類型: nil, boolean, number, string, function, userdata, thread, table,其中 function, (full)userdata, table, thread為引用型別
nil 與 boolean
Lua中表示條件false只有兩個值:nil和false,其它值均表示條件true(0表示條件true)
local a = 0 -- true a = "false" -- true a = false -- false a = nil -- false if a then print("true") else print("false") end
儘管false與nil有時可互相替代,但在table中,給key賦值false只是常規的給它賦值false,而給key賦值nil則表示從table中刪除這個key。
local tab = {a = 1, b = 2}
tab.a = nil
tab.b = false
for key, value in pairs(tab) do
print(key, value)
end
-- b false
number
number型別在Lua中有兩種內部表現方式,可藉助math庫獲取實際型別。
print(type(1)) -- number print(math.type(1)) -- integer print(math.type(1.0)) -- float
標準Lua使用64位整數(範圍:-2^63 ~ 2^63-1) 和64位浮點數,也可把Lua編譯成32位整數(範圍:-2^31 ~ 2^31-1)和32位浮點數;
超出int範圍的值會變成科學計數法;
Lua內部會按規則自動將number型別轉換int或float型別。
string
string型別是不可變的byte序列,string中可包含任意8位的值(0 ~ 2^8-1)。
string既可以是binary string(與編碼無關,如"\0\1"),也可以是text string(如"hello")。
local s1 = "\0\1"
local s2 = "hello"
任何string的長度都是int型別。
table
table型別是一個Dictionary。
- key可以是任何種類(除了nil和NaN),索引的格式為a[key],當key為string時候,可以寫成 a.key
local tab = { a = 1, b = 2 }
tab.a = 2
tab["b"] = 3
- value可以是任何種類(除了nil)。當value為nil時,表示刪除table中該元素
local tab = { a = 1 }
tab.a = nil
print(#tab) -- 0
- table可表示ordinary arrays, lists, symbol tables, sets, records, graphs, trees
local t1 = { "a", "b", "c"} -- ordinary array/ list
- table型別是一個引用型別
function
Lua裡function有兩類: Lua function 和 C function
local function func() end -- lua function
int co_func(lua_State* state){
printf("%d\n",10);
lua_yield(state,1);
return 1;
}
int main()
{
lua_State *state = luaL_newstate();
lua_pushcfunction(thread,co_func); //將C function push到Lua stack上
userdata
userdata型別表示一段記憶體
- userdata分為兩類: full userdata 和 light userdata
- full userdata表示的記憶體由Lua所分配,並且可以由metatable定義額外的操作
- light userdata表示的記憶體由使用者手動分配(malloc)
- userdata由C Lua API建立和修改,無法通過Lua chunk所...
thread
thread實際上是一個coroutine,就算系統只有一個hardware thread,它也支援多個coroutines