lua元表與元方法

2022-05-02 21:33:07 字數 4906 閱讀 2737

lua中提供的元表(metatable)與元方法(metamethod)是一種非常重要的語法,metatable主要用於做一些類似於c++過載操作符式的功能。

lua中提供的元表是用於幫助lua變數完成某些非預定義功能的個性化行為,如兩個table的相加,通過讓兩者指向同一元表並修改該元表的元方法可以實現該功能。

任何table都可以成為任何值的元表,而一組相關的table也可以共享乙個元表。

一些metamethod:

__add(a, b)                     對應表示式 a + b

__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(...)

1、算術類and關係類元方法

先看乙個簡單的例子:

--

我們想讓兩個分數相加,這是一種非預定義的行為

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

print

(s3)

print

(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

print

(w.width)

print

(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

print

(w.width)

print

(w.width1)

print

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