You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua继承链中父类init赋值的实例变量访问为nil问题排查

Lua继承调用中父类init读取属性为nil的问题分析与修复

问题根源

你的class实现里,父类的super实例存在赋值与读取属性逻辑不一致的问题:赋值时属性会被存在子类实例中,但读取时却从super实例自身查找,导致刚赋值就读不到值。

详细过程拆解

  1. 实例创建流程:当调用Cat.new()时,Cat.classdef.new会生成一个空的子类实例instance,然后通过Animal.alloc(instance)创建父类的super对象。这个super对象的元表设置为:

    • __index = classes.Object:读取属性/方法时优先从classes.Object查找
    • __newindex = instance:赋值属性时直接写入子类实例instance
  2. 父类init执行时的矛盾:

    • 调用self.super:init(name)时,init方法内的self是父类的super对象
    • 执行self.id = numAnimals:因为super对象本身没有id属性,触发__newindex,最终把id写入了子类实例instance
    • 紧接着执行print(self.id):此时从super对象自身查找id,找不到就走__index去classes.Object里找,自然返回nil

修复方案

修改classes.Object.alloc方法,让super实例读取属性时优先从子类实例(mastertable)查找,找不到再去父类查找方法:

function classes.Object.alloc (mastertable)
    return setmetatable({}, {
        __index = function(t, k)
            -- 先从子类实例读取属性
            if mastertable[k] ~= nil then
                return mastertable[k]
            end
            -- 找不到再从父类读取方法
            return classes.Object[k]
        end,
        __newindex = mastertable
    })
end

这样调整后,父类init方法里的self.id就能正确读取到之前写入子类实例的属性值,打印语句也能正常输出。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:42:47