首先给大家看一段lua创建对象的代码
function first:new()
local o={}
setmetatable(o,self)
self.__index=self
return o
end
估计大家都敲过好多遍了,这段代码的含义就是:创建一个o,将自身设置为o的元表,然后将自身__index元方法设置为查找自身,但为什么这么做呢?
还有另外一个创建对象的方法
function first:new()
local o={}
setmetatable(o,{__index=self})
return o
end
大家应该知道这两个创建的结果是相同的
这个要从table查询的方式说起:
当访问一个table中不存在的字段时,table就会去查找它元表的__index字段,所以要找到这个不存在的字段,是要两个条件,首先要有元表,其次元表有__index字段。所以第一个案例首先使用setmetatable(o,self)给o设置一个元表,但这时候去访问self的字段会返回nil,因为self中没有__index字段,所以需要定义self.__index=self。
这时第二个案例大家应该也就理解了,setmetatable(o,{__index=self}),就是将一个table {__index=self}设置为o的元表,查询的时候o首先找到它的元表{__index=self},然后在元表中找到__index字段,由__index给它带路,找到了self。
下面是一些有意思的事例,帮助理解
local first={a=100,b=200}
local second={a=300,b=400}
function first:new()
local o={}
setmetatable(o,self)
self.__index=second
return o
end
function second:new()
local o={}
setmetatable(o,first)
self.__index=first
return o
end
-- 这里的调用顺序会有影响哦,先调用first:new(),然后first.__index才存在哦
local t1=first:new()
local t2=second:new()
print(t1.a)
print(t2.a)
答案是:
300
300
local first={a=100,b=200}
local second={a=300,b=400}
function first:new()
local o={}
setmetatable(o,self)
self.__index=self
return o
end
function second:new()
local o={}
setmetatable(o,first)
first.__index=second
return o
end
-- 可以试一下将t1和t2的赋值顺序调换,查看结果
local t1=first:new()
local t2=second:new()
print(t1.a)
print(t2.a)
答案是:
300
300
function second:new()
local o={}
setmetatable(o,{__index={a=55}})
return o
end
local t2=second:new()
print(t2.a)
答案是:
55