lua中提供的元表(metatable)與元方法(metamethod)是一種非常重要的語法,metatable主要用於做一些類似於c++過載操作符式的功能。
lua中提供的元表是用於幫助lua變數完成某些非預定義功能的個性化行為,如兩個table的相加,通過讓兩者指向同一元表並修改該元表的元方法可以實現該功能。
任何table都可以成為任何值的元表,而一組相關的table也可以共享乙個元表。
一些metamethod:
__add(a, b) 對應表示式 a + b1、算術類and關係類元方法__sub(a, b) 對應表示式 a - b
__mul(a, b) 對應表示式 a * b
__div(a, b) 對應表示式 a / b
__mod(a, b) 對應表示式 a % b
__pow(a, b) 對應表示式 a ^ b
__unm(a) 對應表示式 -a
__concat(a, b) 對應表示式 a .. b
__len(a) 對應表示式 #a
__eq(a, b) 對應表示式 a == b
__lt(a, b) 對應表示式 a < b
__le(a, b) 對應表示式 a <= b
__index(a, b) 對應表示式 a.b
__newindex(a, b, c) 對應表示式 a.b = c
__call(a, ...) 對應表示式 a(...)
先看乙個簡單的例子:
--我們想讓兩個分數相加,這是一種非預定義的行為
fraction_a =
fraction_b =
fraction_op={} --
元表--
__add這是metatable,這是lua內建約定的
function
fraction_op.__add(a,b)
res={}
res.numerator=a.numerator*b.denominator+b.numerator*a.denominator
res.denominator=a.denominator*b.denominator
return
resend
--將fraction_a,fraction_b的元表設定為fraction_op
--其中setmetatable是庫函式
setmetatable
(fraction_a,fraction_op)
setmetatable
(fraction_b,fraction_op)
--呼叫的是fraction_op.__add()函式
fraction_c=fraction_a+fraction_b
print(fraction_c.numerator.."/"
..fraction_c.denominator)
--輸出結果
--26/21
再來看乙個深度一點的例子,例舉了算數類的元方法,關係類的元方法,庫定義的元方法。
set={}local metatable={} --
元表--
根據引數列表中的值建立乙個新的集合
function
set.new(a)
local set={}
--將所有由該方法建立的集合的元表都指定到metatable
setmetatable
(set,metatable)
for i,v in
pairs(a) do
set[v]=true
endreturn
setend
--計算兩個集合的並集
function
set.union(a,b)
local res=set.new{}
for i in
pairs(a) do
res[i]=true
endfor i in
pairs(b) do
res[i]=true
endreturn
resend
--計算兩個集合的交集
function
set.intersect(a,b)
local res=set.new{}
for i in
pairs(a) do
res[i]=b[i]
endreturn
resend
--print總是呼叫tostring來格式化輸出
--這裡我們稍作修改庫定義的print
function set.tostring
(a)
local t={}
for i in
pairs(a) do
t[#t+1]=i
endreturn""
end--
判斷a集合是否是b集合的子集
function
set.lessorequal(a,b)
for i in
pairs(a) do
ifnot b[i] then
return
false
endend
return
true
end--
最後將重定向的元方法加入到元表中
metatable.__add=set.union
metatable.__mul=set.intersect
metatable.__tostring=set.tostring
metatable.__le=set.lessorequal
metatable.__eq=function(a,b) return a<=b and b<=a end
metatable.__lt=function(a,b) return a<=b and
not (b<=a) end
s1=set.new
s2=set.new
s3=s1+s2
s4=s1*s2
(s3)
(s4)
print(3+4,3*4) --
新加的方法不改變表本身具有的方法,因為傳入的引數不同,只會讓元方法更完善
s5=set.new
s6=set.new
print(s5<=s6)
print(s5print(s5==s6)
--輸出結果
----
--7 12
--true
--true
--false
2、table訪問的元方法:
算數類和關係類的元方法都為各自錯誤情況定義了行為,他們不會改變語言的常規行為,但lua還是提供了一種可以改變table的行為。有兩種可以改變table的行為:查詢table以及修改table中不存在的字段。
1)、__index元方法
當訪問table中不存在的字段時,得到的結果為nil。如果我們為table定義了元方法__index,那訪問的結果將由該方法決定。
window={}window.prototype=
window.mt={} --
window的元表
function
window.new(o)
setmetatable
(o,window.mt)
return
oend
window.mt.__index=function(table,key) return window.prototype[key] end
w=window.new
(w.width)
(w.width1)
--輸出結果
--100
--nil
2)、__newindex元方法
和__index不同的是,該元方法用於不存在鍵的賦值,而前者用於訪問。
window={}window.prototype=
window.mt={} --
window的元表
function
window.new(o)
setmetatable
(o,window.mt)
return
oend
window.mt.__index=function(table,key) return window.prototype[key] end
window.mt.__newindex=function(table,key,value) window.prototype[key]=value end
w=window.new
w.length=50
(w.width)
(w.width1)
(window.prototype.length)
--輸出結果
--100
--nil
--50
lua元表與元方法
1.首先我們先了解下lua的表 2.元表 是用來定義對table操作的方式表 我們先來看一下問題 t1 t2 我們把這兩張錶拼起來 第一種方法 table.inster t1,t2 1 第二種方法 元表 mt 方法類似於c 的運算子過載可以看出我們過載的是 mt.add function t1,t2...
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...
Lua元表和元表方法
今天學習lua中的元表,書上講的太難懂了,網上搜尋教程也將的模模糊糊,搜了一會總結了一下經驗,跟大家分享一下,希望對您有所幫助。如何設定元表?local t local mt getmetatable t nil setmetatable t,mt 將t1設定為t的元表 getmetatable t...