元表概念
lua中,物件導向是用元表這種機制來實現的
元表(matatable)
lua在建立新的table時不會建立元表,比如以下**就可以演示:
local t =
print(getmetatable(t)) -- nil
設定元表和獲取元表(getmetatable和setmetatable)
使用getmetatable來獲取乙個table或userdata型別變數的元表,當建立新的table變數時,使用getmetatable去獲得元表,將返回nil;同理,我們也可以使用setmetatable去設定乙個table或userdata型別變數的元表
local t = {}
print(getmetatable(t)) -->nil 建立新的table,還沒有設定元表,故為nil
local t1 = {}
setmetatable(t, t1) --設定元表
assert(getmetatable(t) == t1)
任何table都可以作為任何值得元表,而一組相關的table有可以共享乙個通用的元表,此元表描述了它們共同的行為。乙個table甚至可以作為它自己的元表,用於描述其特有的行為。總之,任何搭配形式都是合法的
set = {}
local mt = {} -- 集合的元表
-- 根據引數列表中的值建立乙個新的集合
function
set.new(l)
local
set = {}
setmetatable(set, mt) --每呼叫一次這個函式,就建立乙個set,並設定元表mt
for _, v in pairs(l) do
set[v] = true
end return
setend
-- 並集操作
function
set.union(a, b)
local retset = set.new{} -- 此處相當於set.new({})
for v in pairs(a) do retset[v] = true
end for v in pairs(b) do retset[v] = true
end return retset
end
所有由set.new建立的集合都具有乙個相同的元表,例如
local set1 = set.new()
local set2 = set.new()
print(getmetatable(set1))
print(getmetatable(set2))
assert(getmetatable(set1) == getmetatable(set2)) --他們的元表都是一樣的
最後,我們需要把元方法加入元表中,**如下:
mt.__add = set.union
local set1 =
set.
new()
local set2 =
set.
new()
local set3 = set1 + set2
set.print(set3)
保護元表
保護元表,用字段__metatable。當我們想要保護集合的元表,是使用者既不能看也不能修改集合的元表,那麼就需要使用__metatable欄位了;當設定了該字段時,getmetatable就會返回這個欄位的值,而setmetatable則會引發乙個錯誤;如以下演示**:
function
set.new
(l) local set = {}
setmetatable(set, mt)
for _, v in
pairs(l) do set[v] = true
end mt.__metatable = "you cannot get the metatable"
-- 設定完我的元表以後,不讓其他人再設定
return set
endlocal tb = set.new()
print(tb)
print(getmetatable(tb)) --得到you cannot get the metatable
setmetatable(tb, {}) -- 這兒已經不能設定元表的了
__index元方法:
預設情況下,當我們訪問乙個table中不存在的字段時,得到的結果是nil。但是這種狀況很容易被改變;lua是按照以下的步驟決定是返回nil還是其它值得:
當訪問乙個table的字段時,如果table有這個字段,則直接返回對應的值;
當table沒有這個字段,則會促使直譯器去查詢乙個叫__index的元方法,接下來就就會呼叫對應的元方法,返回元方法返回的值;
如果沒有這個元方法,那麼就返回nil結果。
student = {} -- 建立乙個命名空間
-- 建立預設值表
student.default =
student.mt = {} -- 建立元表
-- 宣告建構函式
function
student.new
(o) setmetatable(o, student.mt) --設定元表
return o
end-- 定義__index元方法
student.mt.__index = function
(table, key)
return student.default[key]
endlocal s = student.new(name = "lisi")
print(s.name) -- >lisi 訪問自身已經擁有的值
print(s.age) -- >18 訪問default表中的值
print(s.id) -- >1101 訪問default表中的值
Lua元表和元表方法
今天學習lua中的元表,書上講的太難懂了,網上搜尋教程也將的模模糊糊,搜了一會總結了一下經驗,跟大家分享一下,希望對您有所幫助。如何設定元表?local t local mt getmetatable t nil setmetatable t,mt 將t1設定為t的元表 getmetatable t...
lua 元表中 newindex元方法
元方法 index 對乙個表a的元素id賦值,如果在表a中元素id不存在,不對id賦值 會呼叫元表中 如果元表存在 的 newindex表,如果表a中存在id這個元素,則對賦值,不呼叫元表中 newindex local newindextable local metablea local tabl...
Lua 元表以及元方法
例如 a 10b 20print a b 我們可以得到30,但是如果兩個table型別相加呢?a b print a b 輸出結果是 lua hello world.lua 3 attempt to perform arithmetic on global a a table value stack...