【发布时间】:2017-02-14 15:05:06
【问题描述】:
我正在尝试添加对属性声明的自动支持,以便类获取自动为它们生成的 getter 和 setter。我使用中间类库作为类的基础。我已经定义了一个处理属性创建的根类。但是,在测试中,只有根类的直接子类才能正常工作。其他人在中间类代码深处给我堆栈溢出错误([string "local middleclass = {..."]:82: stack overflow)。
我的代码是:
local CBaseObject=class('CObjectBase');
function CBaseObject:initialize()
self._init=true;
end;
function CBaseObject:finalize()
self._init=false;
end;
function CBaseObject:_getter_setter(v)
return v;
end;
function CBaseObject:_gen_prop_cache()
rawset(self,'_properties',rawget(self,'_properties') or {});
end;
function CBaseObject:__index(k)
print('GET',k);
self:_gen_prop_cache();
local prop=self._properties[k];
if prop~=nil
then
local getter=self[prop[2] or '_getter_setter'];
return getter(self,prop[1]);
else return nil;end;
end;
function CBaseObject:__newindex(k,v)
print('ME',self.class.name);
print('SET',k,v);
self:_gen_prop_cache();
local prop=self._properties[k];
if prop==nil and self._init or prop
then
if prop==nil then prop={};self._properties[k]=prop;end;
local vv=prop[1];
if type(v)=='table' and #v<4
then
for i=1,3 do prop[i]=v[i];end;
else
prop[1]=v;
end;
local setter=self[prop[3] or '_getter_setter'];
prop[1]=setter(self,prop[1],vv);
else
rawset(self,k,v);
end;
end;
测试类:
local cls=CBaseObject:subclass('test');
function cls:initialize()
self.class.super.initialize(self);
self.health={1000,'_gethealth','_sethealth'};
self.ammo=100;
self:finalize();
end;
function cls:_sethealth(value,old)
print('WRITE:',value,old);
if value<0 then return old;else return value;end;
end;
function cls:_gethealth(value)
print('READ:',value);
return value/1000;
end;
local cls2=cls:subclass('test2');
function cls2:initialize()
self.class.super.initialize(self);
self.ammo=200;
self:finalize();
end;
function cls2:_sethealth(value,old)
print('WRITE_OVERRIDEN:',value,old);
return value;
end;
local obj=cls2(); --change this to cls() for working example.
obj.health=100;
obj.health=-100;
print(obj.health,obj._properties.health[1]);
print(obj.ammo,obj._properties.ammo[1]);
我使用https://repl.it/languages/lua 运行我的代码。所以,问题是,我所做的是否是正确的方法?是否可以以与使用的库兼容的更简单方式添加属性支持?或者我应该使用另一个,然后呢?
编辑:经过实验,我发现构造 self.class.parent.<method>(<...>) 是错误的罪魁祸首。我用实际的父类替换了所有此类事件。那是唯一的问题,似乎在那之后代码开始没有错误地工作。
【问题讨论】:
-
如果您可以自己回答问题,请回答,不要编辑问题...顺便说一句,您可以删除这些分号。在 Lua 中它们不是必需的。
-
但我仍然不确定我的所作所为不能做得更好。而且我坚持使用分号,因为我不想破坏我在其他语言中需要它们的习惯,基本上所有这些。
标签: oop properties lua