lua 深入用法
C API
兩種觀點(Lua作爲擴展性語言和可擴展的語言)對應的C和Lua中間有兩種交互方式。第一種,C作爲應用程序語言,Lua作爲一個庫使用;第二種,反過來,Lua作爲程序語言,C作爲庫使用。這兩種方式,C語言都使用相同的API與Lua通信,因此C和Lua交互這部分稱爲C API。
C API是一個C代碼與Lua進行交互的函數集。他有以下部分組成:讀寫Lua全局變量的函數,調用Lua函數的函數,運行Lua代碼片斷的函數,註冊C函數然後可以在Lua中被調用的函數,等等。(本書中,術語函數實際上指函數或者宏,API有些函數爲了方便以宏的方式實現)
C API遵循C語言的語法形式,這Lua有所不同。
在C和Lua之間通信關鍵內容在於一個虛擬的棧.
幾乎所有的API調用都是對棧上的值進行操作,所有C與Lua之間的數據交換也都通過這個棧來完成。另外,你也可以使用棧來保存臨時變量。棧的使用解決了C和Lua之間兩個不協調的問題:第一,Lua會自動進行垃圾收集,而C要求顯示的分配存儲單元,兩者引起的矛盾。第二,Lua中的動態類型和C中的靜態類型不一致引起的混亂。
string 相關
string.split = function(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end
table 相關
__index
訪問
table中的元素,不存在的時候,尋找__index
Window = {}
Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}
Window.mt = {}
function Window.new(o)
setmetatable(o ,Window.mt)
return o
end
Window.mt.__index = function (t ,key)
-- body
return 1000
end
w = Window.new{x = 10 ,y = 20}
print(w.wangbin)
__newindex
設置
table中的元素,不存在的時候,進行賦值
Window.mt = {}
function Window.new(o)
setmetatable(o ,Window.mt)
return o
end
Window.mt.__index = function (t ,key)
return 1000
end
Window.mt.__newindex = function (table ,key ,value)
if key == "wangbin" then
rawset(table ,"wangbin" ,"yes,i am")
end
end
w = Window.new{x = 10 ,y = 20}
w.wangbin = "55"
print(w.wangbin)
rawget
爲了繞過__index
Window = {}
Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}
Window.mt = {}
function Window.new(o)
setmetatable(o ,Window.mt)
return o
end
Window.mt.__index = function (t ,key)
return 1000
end
Window.mt.__newindex = function (table ,key ,value)
if key == "wangbin" then
rawset(table ,"wangbin" ,"yes,i am")
end
end
w = Window.new{x = 10 ,y = 20}
print(rawget(w ,w.wangbin))
打印結果是:nil。這裏的元表中__index函數就不再起作用了
rawset
爲了繞過__newindex
Window = {}
Window.prototype = {x = 0 ,y = 0 ,width = 100 ,height = 100,}
Window.mt = {}
function Window.new(o)
setmetatable(o ,Window.mt)
return o
end
Window.mt.__index = function (t ,key)
return 1000
end
Window.mt.__newindex = function (table ,key ,value)
table.key = "yes,i am"
end
w = Window.new{x = 10 ,y = 20}
w.wangbin = "55"
然後我們的程序就stack overflow了。可見,程序陷入了死循環。
迭代器
for後面跟幾個數值,則迭代函數就需要返回多少個數值,遇到第一個爲nil的,則迭代器終止。
無狀態迭代器
local tb = {"aa", "bb", "cc"}
local function iterm(tb, idx)
local len = #tb
if idx > len then
return
end
idx = idx + 1
return idx, tb[idx]
end
for k, v in iterm,tb,0 do
print(k, v)
end
有狀態迭代器: 本質上是利用了閉包函數。
local tb = {"aa", "bb", "cc"}
local function iterm(tb)
local idx = 0
local len = #tb
return function()
if idx > len then
return
end
idx = idx + 1
return tb[idx]
end
end
for k in iterm(tb) do
print(k)
end