天天看點

Lua元表(Metatable)

Lua元表

運算符重載

lua中的table不能相加等操作,元表可以用來做運算符重載;

--加号+重載
local mt = {}
--定義mt.__add元方法(其實就是元表中一個特殊的索引值)為将兩個表的元素合并後傳回一個新表
mt.__add = function(t1,t2)
	local temp = {}
	for _,v in pairs(t1) do
		table.insert(temp,v)
	end
	for _,v in pairs(t2) do
		table.insert(temp,v)
	end
	return temp
end

local t1 = {1,2,3}
local t2 = {2}
--設定t1的元表為mt
setmetatable(t1,mt)

local t3 = t1 + t2
--輸出t3
local st = "{"
for _,v in pairs(t3) do
	st = st..v..", "
end
st = st.."}"
print(st)

--結果:{1, 2, 3, 2, }
           

運算符相關原方法:

函數 描述
__add 運算符 +
__sub 運算符 -
__mul 運算符 *
__ div 運算符 /
__mod 運算符 %
__unm 運算符 -(取反)
__concat 運算符 ..
__eq 運算符 ==
__lt 運算符 <
__le 運算符 <=

__call

重載括号()方法;

local mt = {}
--__call的第一參數是表自己
mt.__call = function(mytable,...)
    local sum = 0
    for k,v in ipairs{...} do
        sum = sum + v
    end
    return	sum
end

t = {}
setmetatable(t,mt)

print (t(12,3,5))

--結果:20
           

__tostring

重寫print(table)的方法;初始方法是列印記憶體位址;

table = {1,2,3,4}

print(table)

mytable = setmetatable(table,{
__tostring = function(table)
	local str = ""
	for k,v in pairs(table)do
		str = str..v
	end
	return str
end
})

print(mytable)
           

結果:

Lua元表(Metatable)

__index

調用不存在索引時,如果有__index方法會被調用;感覺有點像寫好的錯誤處理;

__index可以是方法,也可以是個表;

表中不存在鍵值,查找元表中__index方法,或 __index表中有無鍵值;

local mt = {}

mt.__index = function(mt,key)
	return "鍵值對不存在"..key
end

t1 = {1,23,22}
print(t1.key)

setmetatable(t1,mt)

print(t1.key)

mt.__index = {key1 = "我不存在"}

print(t1.key1)
--結果:
--nil
--鍵值對不存在key
--我不存在
           

__newindex

重寫=等号,表中的複制操作替換成該方法;

local mt = {}
t = setmetatable({key = "littlePerilla---1111"},{ __newindex = mt})

print(t.key)

t.key2 = "littlePerilla---2222"

print(t.key2)
print(mt.key2)

t = setmetatable({key = "littlePerilla---1111"}, {
	__newindex = function(t, key, value)
		rawset(t, key, "I am "..value)
	end
})

t.key3 = "littlePerilla---3333"
print(t.key3)

--結果:
--littlePerilla---1111
--nil
--littlePerilla---2222
--I am littlePerilla---3333
           

rawget 和 rawset

rawget直接擷取表中索引的value,不通過__index

rawset直接給索引指派,不通過__newindex

table = {key = "littlePerilla"}
print(rawget(table,"key"))

rawset(table,"key2","littlePerilla22")
print(table.key2)

--結果:
--littlePerilla
--littlePerilla22
           

浮生若夢,為歡幾何