Lua OOP实现遇变量覆盖问题:如何阻止表变量被重写?
问题原因与修正方案
你的核心错误是在new方法中修改了类表Atom的属性,而非新创建的实例属性,导致所有实例共享了类表的同一个值。
错误分析
在Lua的:new()方法中,self指向的是调用这个方法的对象——也就是Atom类本身。你把px、py等属性赋值给self,相当于直接修改Atom全局类表的字段。而你创建的atom实例是空表,当访问a[i].px时,因为实例自身没有px字段,会通过__index元方法去Atom类表中查找,所以所有实例拿到的都是最后一次修改的类表px值,自然全部相同。
另外,你的Atom定义中键的写法不规范("px" = 0),虽然Lua允许,但通常直接写px = 0即可。
修正后的代码
Atom = { px = 0, py = 0, vx = 0, vy = 0, r = 255, g = 255, b = 255 } Atom.__index = Atom -- 提前设置元方法,无需每次创建实例重复设置 function Atom:new(pos_x, pos_y, r_t, g_t, b_t) local atom = {} setmetatable(atom, self) -- 将属性赋值给新创建的实例,而非类表 atom.px = pos_x or self.px atom.py = pos_y or self.py atom.vx = self.vx atom.vy = self.vy atom.r = r_t or self.r atom.g = g_t or self.g atom.b = b_t or self.b return atom end
关键修正点
- 属性赋值目标改为实例:把
self.px = ...换成atom.px = ...,让每个实例拥有独立的属性副本,不再共享类表字段。 - 提前设置
__index元方法:在类表上一次性设置__index = Atom,避免每次调用new都重复执行,提升效率。 - 使用类表字段作为默认值:当实例没有传入参数时,用类表的默认值初始化,但实例会自己存储这份值,不会影响其他实例或类表。
运行修正后的代码,每个a[i].px都会是不同的随机值,符合预期。
内容的提问来源于stack exchange,提问作者Toni Arjona
相关产品推荐
相关产品推荐

