You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Lua元方法改写问题:为何重写后的代码无法正常运行?

咱们来一步步拆解你改写后的代码为什么不工作,以及如何修复:

1. 你没有创建独立的实例,而且返回的是数字而非表

在你最初的代码里,tb.new()每次都会创建一个全新的super表,给它设置b属性,再把元表绑定到这个新表上——这正是每个实例能保留自己独立值的原因。

但在改写后的代码里:

  • tb是一个全局共享的单一表,每次调用ins(a)都会覆盖tb.a的值,后调用的会把之前的覆盖掉。
  • 更关键的是,ins(a)返回的是tb.a,也就是一个数字,而不是表本身。所以当你执行ins(2)..ins(3)时,其实是在拼接两个数字2和3。Lua中..对数字的默认行为是把它们转成字符串再拼接,结果会是"23",完全不是你想要的相加逻辑。

2. 你的__concat元方法绑定错了对象

你把__concat定义在了tb这个表上,但你在拼接时根本没用到tb作为实例。你传给..的是数字,数字使用的是Lua默认的数字元表,根本不会调用你自定义的__concat方法。

正确的改写版本

我们需要回到“为每个值创建独立表实例”的逻辑,并且把元表绑定到每个实例上:

-- 定义包含__concat逻辑的元表
local instanceMeta = {
    __concat = function(a, b)
        return a.value + b.value
    end
}

-- 创建实例的函数
local function ins(a)
    -- 为每个实例创建新表,存储对应的值
    local newInstance = {value = a}
    -- 把元表绑定到这个新实例上
    setmetatable(newInstance, instanceMeta)
    return newInstance
end

-- 测试代码
local f = ins(2)
local t = ins(3)
print(f .. t) -- 现在会输出5,符合预期!

为什么这个版本能工作:

  • 每次调用ins()都会生成一个全新的表,每个实例都能保留自己的数值,不会互相覆盖。
  • 我们把带有自定义__concat的元表绑定到了每个实例表上。当对两个实例表使用..时,Lua会从它们的元表中找到__concat方法,执行我们定义的相加逻辑。

内容的提问来源于stack exchange,提问作者Xuer

火山引擎 最新活动