Lua元表 · 花生肉泥

Metatable元表

lua中的每个值都可以用一个metatable

两个table类型的变量,你是无法直接用 + 操作的,如果你定义了一个指定的函数,就可以进行了

setmetatable(table,metatable):对指定table设置元表(metatable),如果元表中存在__metatable键值,setmetatable会失败

getmetatable(table):返回对象的元表

元表创建

lua在创建新的table时不会创建元表

1  
2  
local t = {1,2}  
print(getmetatable(t))       

—|—

使用getmetatable来获取一个table或userdata类型变量的元表,当创建新的table变量时,使用getmetatable去获得元表,将返回nil,同理,我们也可以使用setmetatable去设置一个table或者userdata类型变量的元表

lua代码中,只能设置table元表

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
local t = {}  
setmetatable(t,t1)  
assert(getmetatable(t) == t1)  
  
print(getmetatable("hello world"))  
print(getmetatable(10))  
  
  
  
  
=====结果=====  
nil  
table:0061DE68  
nil  

—|—

__index元方法

当我们访问一个table中不存在的字段时,得到的结果是nil,但是这种状况很容易被改变,lua是按照以下步骤决定是返回nil还是其他的值:

当访问一个table字段时,如果table有这个字段,则直接返回对应值。

当table没有这个字段,则会促使解释器去查找一个叫__index的元方法,接下来就会调用对应的元方法,返回元方法的值。

如果没有这个元方法,那么返回nil结果

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
Windows = {}     -- 创建一个命名空间  
  
-- 创建默认值表  
Windows.default = {x=0,y=0,width=100,height=100,color={r=255,g=255,b=255}}  
  
Windows.mt = {}     -- 创建元表  
  
-- 声明构造函数  
function (o)  
     setmetatable(o,Windows.mt)  
     return 0  
end  
  
-- 定义__index元方法  
Windows.mt.__index = function(table,key)  
     return Windows.default[key]  
end  
  
local win = Windows.new({x=10,y=10})  
print(win.x)     -- 10  
print(win.width)     -- 100  
print(win.color.r)     -- 255  

—|—

__index元方法不必一定是一个函数,他还可以是一个table

__newindex元方法

newindex元方法与 index类似, newindex用于更新table中的数据,而 index用于查询table中的数据

lua解释器先判断这个table是否有元表

如果有元表,就查找元表中是否有__newindex元方法,如果没有元表,就直接添加这个索引,然后对应的赋值

如果有这个__newindex元方法,lua解释器就执行它,而不是执行赋值

如果这个__newindex对应的不是一个函数,而是一个table,lua解释器就在这个table中执行赋值么不是对原来的table

1  
2  
3  
4  
5  
6  
7  
8  
9  
local tb1 = {}  
local tb2 = {}  
tb1.__newindex = tb2  
tb2.__newindex = tb1  
  
setmetatable(tb1,tb2)  
setmetatable(tb2,tb1)  
  
tb1.x  = 10  

—|—

糖果

糖果
LUA教程

Lapis框架的常用处理方法

Lapis框架的常用处理方法 Continue reading

MoonScript实现选择排序

Published on February 26, 2017

MoonScript与Redis客户端

Published on January 19, 2017