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)

结果:

image-20211009105138022

__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
posted @ 2021-10-09 11:26  小紫苏  阅读(259)  评论(0编辑  收藏  举报