Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 中间类:添加对属性的getter setter支持_Oop_Properties_Lua - Fatal编程技术网

Oop 中间类:添加对属性的getter setter支持

Oop 中间类:添加对属性的getter setter支持,oop,properties,lua,Oop,Properties,Lua,我正在尝试添加对属性声明的自动支持,以便类能够自动为它们生成getter和setter。我使用中产阶级图书馆作为课程的基础。我已经定义了一个处理属性创建的根类。然而,在测试中,只有根类的直接子类可以正常工作。其他人在中间类代码的深处给出堆栈溢出错误([string“local middleclass={…”):82:stack overflow) 我的代码是: local CBaseObject=class('CObjectBase'); function CBaseObject:initial

我正在尝试添加对属性声明的自动支持,以便类能够自动为它们生成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 CBaseObject=class('CObjectBase');
函数CBaseObject:initialize()
self._init=true;
结束;
函数CBaseObject:finalize()
self._init=false;
结束;
函数CBaseObject:\u getter\u setter(v)
返回v;
结束;
函数CBaseObject:\u gen\u prop\u cache()
rawset(self,“u属性”、rawget(self,“u属性”)或{};
结束;
函数CBaseObject:uu索引(k)
打印('GET',k);
self:_gen_prop_cache();
局部属性=自身属性[k];
如果prop~=nil
然后
本地getter=self[prop[2]或''u getter\u setter'];
返回getter(self,prop[1]);
否则返回零;结束;
结束;
函数CBaseObject:uu newindex(k,v)
打印('ME',self.class.name);
打印('SET',k,v);
self:_gen_prop_cache();
局部属性=自身属性[k];
如果prop==nil和self.\u init或prop
然后
如果prop==nil,那么prop={};self.\u属性[k]=prop;end;
本地vv=道具[1];
如果类型(v)=‘表’和#vEnrique García Cota(创作者)启发了我,我认为这是一个关于中产阶级的好故事。
他建议创建并使用一个

我在测试/使用此mixin配方时做了一些小改动。目前我使用的配方如下所示:

-- properties.lua
local Properties = {}

function Properties:__index(k)
    local getter = self.class.__instanceDict["get_" .. k]
    if getter ~= nil then
        return getter(self)
    end
end

function Properties:__newindex(k, v)
    local setter = self["set_" .. k]
    if setter ~= nil then
        setter(self, v)
    else
        rawset(self, k, v)
    end
end

return Properties
您必须为属性创建
函数get
*和
函数集
*(或根据需要修改上面的字符串模式)

例如:

local class = require('middleclass')
local Properties = require('properties')

local Rect = class('Rect'):include(Properties)

function Rect:initialize(x, y, w, h)
  self.x = x
  self.y = y
  self.w = w
  self.h = h
end

function Rect:get_right()
  return self.x + self.w
end

function Rect:set_right(right)
  self.x = self.x + right - self.right
end

r = Rect:new(10,10, 100, 100)

print(r.right) -- 110
print(r:get_right()) -- 110
r.right = 200
print(r.right) -- 200
print(r.x) -- 100
通过这种方式,您可以在想要具有属性的任何类中使用此mixin,只需在其上创建
get_
*和
set_
*函数

然而,他也说:

我不太喜欢Lua中的getter/setter。在其他语言中,我可以接受它们;例如在ruby中,它们集成在语言的消息传递机制中

但在Lua中,它们是额外的语法糖,并且有可能使事情变得更“神奇”(对不熟悉代码的人来说是意外的)

性能说明:但是,值得一提的是,使用
\uu index
函数(如示例所示)会严重影响代码的性能(与
\uu index
表相比)。 就个人而言,在使用getter和setter一段时间之后(由于我对Python的偏见),我决定显式地编写东西,不再依赖它们。
当然,这取决于性能是否对代码至关重要。

如果您可以自己回答问题,请回答,不要编辑问题……顺便说一句,您可以删除这些分号。它们在Lua中不是必需的。但我仍然不确定我做了什么不能做得更好。我坚持使用分号,因为我不想破坏我的习惯其他语言需要它们,基本上所有的。
local class = require('middleclass')
local Properties = require('properties')

local Rect = class('Rect'):include(Properties)

function Rect:initialize(x, y, w, h)
  self.x = x
  self.y = y
  self.w = w
  self.h = h
end

function Rect:get_right()
  return self.x + self.w
end

function Rect:set_right(right)
  self.x = self.x + right - self.right
end

r = Rect:new(10,10, 100, 100)

print(r.right) -- 110
print(r:get_right()) -- 110
r.right = 200
print(r.right) -- 200
print(r.x) -- 100