Lua重要概念梳理

元表的概念


首先我们先看下面的代码

local t = {}
t.prototype = {
    x = 100,
    y = 100,
    width = 50,
    height = 50
}
t.mt = {}
function t.new(value)
    setmetatable(value, t.mt)
    return value
end
t.mt.__index = t.prototype

t.mt.__newindex = function(table, key, value)
    if key == "tomyuan" then
        rawset(table, key, "Yes")
    end
end
-- 处理
local instance = t.new({x = 33, y = 33})
instance.tomyuan = "YuanBo"
print(instance.tomyuan)
print(instance.x)
print(instance.y)
print(instance.width)
print(instance.height)

运行结果如下

Yes
33
33
50
50

上述我们就更改了原表的行为方法

__index

当我们访问表中的一个元素不存在时,则会去寻找 __index 元方法,如果存在则会返回结果,否则返回nil

local t = {}
t.prototype = {
    x = 100,
    y = 100,
    width = 50,
    height = 50
}
t.mt = {}
function t.new(tb)
    setmetatable(tb, t.mt)
    return tb
end
--
t.mt.__index = function(tb, key)
    if key == "TomYuan" then
        return "YuanBo"
    else
        return "Other"
    end
end
--
local instance = t.new({
    x = 100,
    y = 100
})
print(instance.TomYuan)
print(instance.x)
print(instance.width)

运行结果如下
YuanBo
100
Other

__newindex

当给你的表中不存在的key进行赋值时,lua解释器则会寻找__newindex 元方法,发现存在该方法,则执行该方法进行赋值,通过rawset来进行赋值操作

local t = {}
t.prototype = {
    x = 100,
    y = 100,
    width = 50,
    height = 50
}
t.mt = {}
function t.new(tb)
    setmetatable(tb, t.mt)
    return tb
end

t.mt.__newindex = function(tb, key, value)
    if key == "TomYuan" then
        rawset(tb, key, "Yuan Bo")
    end
end

--
local instance = t.new({
    x = 100,
    y = 100
})
instance.TomYuan = "Who"
print(instance.TomYuan)

输出Yuan Bo

rawget和rawset

rawget是为了绕过__index而出现的,还是上面的代码

local t = {}
t.prototype = {
    x = 100,
    y = 100,
    width = 50,
    height = 50
}
t.mt = {}
function t.new(tb)
    setmetatable(tb, t.mt)
    return tb
end

t.mt.__newindex = function(tb, key, value)
    if key == "TomYuan" then
        rawset(tb, key, "Yuan Bo")
    end
end

--
local instance = t.new({
    x = 100,
    y = 100
})
instance.TomYuan = "Who"
print(rawget(instance ,instance.TomYuan))

输出的nil
针对rawset,如果我们上面代码这么写

local t = {}
t.prototype = {
    x = 100,
    y = 100,
    width = 50,
    height = 50
}
t.mt = {}
function t.new(tb)
    setmetatable(tb, t.mt)
    return tb
end

t.mt.__newindex = function(tb, key, value)
    if key == "TomYuan" then
        tb.key = "Yuan Bo"
    end
end

--
local instance = t.new({
    x = 100,
    y = 100
})
instance.TomYuan = "Who"
print(instance.TomYuan)

此时输出了nil,如果__newindex里面这样的呢?

t.mt.__newindex = function(tb, key, value)
    tb.key = "Yuan Bo"
end

则会报如下错误

stack traceback:
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    ...
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:15: in function '__newindex'
    /usercode/file.lua:23: in main chunk
__index 和 __newindex的区别,__index是直接取表的值,没有对应的key,则根据__index返回,__newindex主要用于表不存在的key的赋值操作。

欢迎留言

avatar
  Subscribe  
Notify of