lua中的元表和元方法

2021-07-22 11:39:31 字數 3103 閱讀 3146

元表概念

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...