Lua继承链中父类init赋值的实例变量访问为nil问题排查
Lua继承调用中父类init读取属性为nil的问题分析与修复
问题根源
你的class实现里,父类的super实例存在赋值与读取属性逻辑不一致的问题:赋值时属性会被存在子类实例中,但读取时却从super实例自身查找,导致刚赋值就读不到值。
详细过程拆解
实例创建流程:当调用
Cat.new()时,Cat.classdef.new会生成一个空的子类实例instance,然后通过Animal.alloc(instance)创建父类的super对象。这个super对象的元表设置为:__index = classes.Object:读取属性/方法时优先从classes.Object查找__newindex = instance:赋值属性时直接写入子类实例instance
父类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
相关产品推荐
相关产品推荐

