课时 11 · 元表与元方法
课时 11 · 元表与元方法(Lua 进阶):理解元表机制并用于扩展表。含可运行的示例代码、练习与验收要点,示例锁定 Lua 5.1,可在站内在线运行验证。
本课的代码可以就地复制;点代码块右上角的「运行这段」, 会带着这段代码打开 Lua 在线运行器 并直接跑出结果 (课程示例统一按 5.1 跑;运行器里也能切到 5.3)。
本课的代码跑在 996 引擎里,用到的是服务端接口(changeexp、 SetInt 这类),在线运行器里没有这些函数。 每个函数的签名都能在 文档检索 里按名字查到原文。
本课目标
- 理解元表机制并用于扩展表。
知识讲解
元表(metatable)是普通表,通过 setmetatable 挂到另一张表上,控制后者的行为。常用元方法:__index(访问不存在键时回调,可实现继承与默认值)、__newindex(给不存在键赋值时回调,可实现只读表)、__add/__sub 等(运算符重载)、__tostring(print 时的表现)、__call(把表当函数调用)。rawget/rawset 绕过元方法直接读写。
示例:元表基础
local defaults = { hp = 100 }
local obj = setmetatable({}, { __index = defaults })
print(obj.hp) -- 100(继承默认值)
local ro = {}
setmetatable(ro, {
__newindex = function() error('只读表,禁止写入') end
})
local ok, err = pcall(function() ro.x = 1 end)
print('写入被拒绝:', err) -- 只读表生效
练习任务
- 实现只读表与带默认值的表:只读表写入时报错;默认值表读取缺省键时返回预设值,读取已有键返回原值。
参考:只读表与默认值表
function readonly(t)
return setmetatable({}, {
__index = t,
__newindex = function() error('attempt to write readonly table') end,
})
end
function with_default(default)
return setmetatable({}, { __index = function(_, k) return default[k] end })
end
local cfg = with_default({ gold = 1000 })
print(cfg.gold, cfg.notexist) -- 1000 nil(default 中无此键)
本篇依据
- 《996 新三端 Lua 开发教学技术手册》课时 11
参数与取值以你本机版本的官方帮助文档为准,不同版本之间有过调整。