Lua元表和元表方法

 

--[[
今天学习lua中的元表,书上讲的太难懂了,网上搜索教程也将的模模糊糊,
搜了一会总结了一下经验,跟大家分享一下,希望对您有所帮助。
--]]
--如何设置元表?
local t = {}
local mt = {}
getmetatable(t)--nil
setmetatable(t,mt)--将t1设置为t的元表
getmetatable(t)--0xb67660

-- __add元表方法

local a = {v = 100}
local b = {v = 300}
local mt = {}
mt.__add = function(a,b)
    return a.v + b.v    
end

setmetatable(a,mt)

print(a+b)

--运行结果
400

--[[
 __index和__newindex元表方法
"index": 索引 table[key]。 当 table 不是表或是表 table 中不存在key 这个键时,这个事件被触发。 
此时,会读出 table 相应的元方法。尽管名字取成这样, 这个事件的元方法其实可以是一个函数也可以是一张表。
 如果它是一个函数,则以 table 和 key 作为参数调用它。如果它是一张表,最终的结果就是以 key 取索引这
张表的结果。(这个索引过程是走常规的流程,而不是直接索引, 所以这次索引有可能引发另一次元方法。

"newindex": 索引赋值 table[key] = value 。 和索引事件类似,它发生在 table 不是表或是表 table 中不存在 
key 这个键的时候。 此时,会读出 table 相应的元方法。同索引过程那样, 这个事件的元方法即可以是函数,也可以是一张
表。 如果是一个函数, 则以 table、 key、以及 value 为参数传入。如果是一张表, Lua 对这张表做索引赋值操作。
(这个索引过程是走常规的流程,而不是直接索引赋值, 所以这次索引赋值有可能引发另一次元方法。)一旦有了 "newindex"
 元方法, Lua 就不再做最初的赋值操作。(如果有必要,在元方法内部可以调用 rawset 来做赋值。
]]

-- __index和__newindex函数
local mt = { 
mt.__index = function(t, k)
    print("call index function",t,k)
end

mt.__newindex = function(t,k,v)
    print("call new index function",t,k,v)
end

mt.__call = function(f,...)
    print(...)
end
local data = {}
setmetatable(data,mt)
local a = data.a
data.a = 10

--运行结果
call index function	table: 0x1905660	a
call new index function	table: 0x1905660	a	10

-- __index和_newindex表
local a = {10,20,30,40,50}
local b = {100,200,300,400,500}

local mt = {}
local t = {}
setmetatable(t,mt)

mt.__index = a
mt.__newindex = b

print(t[1]) -- 10
print(t[3]) -- 30

t[1] = 999
t[2] = 888

print(b[1]) -- 999
print(b[2]) -- 888

--运行结果
10
30
999
888

总结:
local a = data.a --t.a此处调用t表中的a键值,没有找到这个键值,mt元表中就会触发__index元表方法。
data.a = 100 --t.a此处进行赋值,没有找到这个键值,mt元表中就会触发__newindex元表方法。

我们再来写一个只读元表
function read_only_table(t)
    local a = {}
    local mt = {__index = t,__newindex = function()
error("readonly table") end}
    setmetatable(a,mt)
    return a
end
local value=read_only_table{10,20,30,40,50,60}
--这里的read_only_table{10,20,30,40,50,60}等价于rad_only_table({10,20,30,40,50,60})

print(value[1])
value[1] = 55555

--运行结果
10
lua: main.lua:4: readonly table
stack traceback:
	[C]: in function 'error'
	main.lua:4: in metamethod '__newindex'
	main.lua:11: in main chunk
	[C]: in ?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值