您的位置:首页 > 编程语言 > Lua

lua __index __newindex upvalue 示例

2012-11-15 09:47 369 查看
项目中有个公会对象,数据大部分存在data中,之前都是 u.data.point这样访问,太麻烦了。

于是通过设置__index 使之可以直接访问属性,u.point。

但是还是不能直接改属性,u.point = 4,所以再设置了__newindex。



在设置了setmetatable之后,不能直接给u添加新属性,因为设置了__newindex,新的属性将直接加到u.data中的。



[c-sharp]
view plaincopyprint?

Union = {
data = nil,
dirty = nil,
}
--- 生成新的对象
function Union:new(o)
o = o or {}
setmetatable(o,self)
self.__index = self
return o
end
--- 初始化Union数据
function Union:init(data)
self:initTable()
self.data = data
local meta = {}
meta.__index = function (table, key)
if Union[key] ~= nil then
return Union[key]
else
return self.data[key]
end
end
meta.__newindex = function(table,key, value)
self.data[key] = value
end
setmetatable(self, meta)
end
function Union:initTable()
if self.data == nil then
self.data = {}
end
if self.dirty == nil then
self.dirty = {}
end
end
function Union:print()
print(self.point, self.data.point)
end
function pt()
print(data1.point, data2.point, u.point, u.data.point)
end
u = Union:new()
data1 = {point = 3}
data2 = {point = 103}
u:init(data1)
pt()
u.point = 4
pt()
u.data = data2
pt()
u.point = 104
pt()

[c-sharp] 
view plaincopyprint?

function Union:init(data)  
    self:initTable()  
    self.data = data  
    local meta = {}  
    meta.__index = function (table, key)  
        if Union[key] ~= nil then  
            return Union[key]  
        else  
            return self.data[key]  
        end  
    end  
    meta.__newindex = function(table,key, value)  
        self.data[key] = value  
    end  
    setmetatable(self, meta)  
end  

function Union:init(data)
	self:initTable()
	self.data = data
	local meta = {}
	meta.__index = function (table, key)
		if Union[key] ~= nil then
			return Union[key]
		else
			return self.data[key]
		end
	end
	meta.__newindex = function(table,key, value)
		self.data[key] = value
	end
	setmetatable(self, meta)
end


3 103 3 3

4 103 4 4

4 103 103 103

4 104 104 104



2.错误的__newindex

[c-sharp]
view plaincopyprint?

function Union:init(data)
self:initTable()
self.data = data
local meta = {}
meta.__index = function (table, key)
if Union[key] ~= nil then
return Union[key]
else
return self.data[key]
end
end
meta.__newindex = self.data
setmetatable(self, meta)
end

[c-sharp] 
view plaincopyprint?

function Union:init(data)  
    self:initTable()  
    self.data = data  
    local meta = {}  
    meta.__index = function (table, key)  
        if Union[key] ~= nil then  
            return Union[key]  
        else  
            return data[key]  
        end  
    end  
    meta.__newindex = function(table,key, value)  
        self.data[key] = value  
    end  
    setmetatable(self, meta)  
end  

function Union:init(data)
	self:initTable()
	self.data = data
	local meta = {}
	meta.__index = function (table, key)
		if Union[key] ~= nil then
			return Union[key]
		else
			return data[key]
		end
	end
	meta.__newindex = function(table,key, value)
		self.data[key] = value
	end
	setmetatable(self, meta)
end


3 103 3 3

4 103 4 4

4 103 4 103

4 104 4 104

对象A在内部可以修改HP.外部对象只能访问对象A的HP,不能修改.

这东西其实可以用__index和__newindex来实现.

__index指向对象A,这样就可以访问;

__newindex重写,修改hp的话,就禁止.就可以完成他的需求.

下面给出简单的代码:

这里影响程序的不同结果是upvalue导致的。

由于一般程序中有可能动态改data。所以建议用function设置__index和__newindex,尤其注意各个不同函数中self指向的是什么对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: