两个表用 == 比较,学员以为比的是内容——实际不同表的 == 恒为 false,除非元表里定义了 __eq;而定义了 __eq 的表,比较结果全由元方法说了算。想在"不管元表"的前提下判断两张表是不是同一张,== 帮不上忙。错误场景:
local t1 = setmetatable({}, { __eq = function() return true end })
local t2 = setmetatable({}, { __eq = function() return true end })
print(t1 == t2)
print(rawequal(t1, t2))
t1 == t2 输出 true(元方法放行一切),rawequal 输出 false(确实是两张不同的表)——元方法可以骗过 ==,骗不过 rawequal。
rawequal(a, b) 不经元方法,直接比较两个值的原始同一性,适合对象池判同、身份校验这类"只认本体"的场景。规范写法。示例代码如下:
local function isSameObject(a, b)
return rawequal(a, b)
end
local poolA, poolB = {}, {}
print(isSameObject(poolA, poolA))
print(isSameObject(poolA, poolB))
同一张表判 true,两张空表判 false——内容再像也不是本体。
三步验证:rawequal(1, 1.0) 返回 true(同为数值且值相等);rawequal("1", 1) 返回 false(类型不同不做转换);rawequal(nil, nil) 返回 true——三种基础类型的比较规则与 == 的原始语义一致,区别只在元表拦截。
rawequal 属于 raw 系列原语:rawget 与 rawset 不经元方法读写表字段,是元表拦截之外的最短路径。示例代码如下:
local obj = setmetatable({}, { __index = function() return 99 end })
print(obj.any)
print(rawget(obj, "any"))
obj.any 走 __index 代理拿到 99,rawget 直查表本体拿到 nil——读取路径的差异一目了然。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏】 一、一行代码拆解:if CONTRIB = price then CONTRIB = CONTRIB - pric…
【语法】 一、隐蔽陷阱:三个物品的全排列共 6 种,手写三重循环出 27 种含大量重复——递归交换法:固定一位、递归排其余、…
【语法】 一、抛坑提问:成就池 50 项,玩家已解锁 32 项,剩下的怎么一遍筛出?差集运算——以全集为基准,遍历时查已有集…
【语法】 一、抛坑提问:3 根柱子 5 个盘子从甲柱挪到丙柱,每次只能移一个且大盘不压小盘——把"挪 n 个"分解成"挪 n…
【游戏】 一、一行代码拆解:CASTING[actor] = nil —— 回城打断的核心:施法期间被攻击即清空施法状态并返…
【游戏】 一、一行代码拆解:APPLY[acc] = os.time() —— 入会审批的全部骨架:申请进队列带时间戳,官员…