1. 程式人生 > 其它 >Lua值與型別深入理解

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