Lua重要概念梳理

Lua重要概念梳理

元表的概念

首先我們先看下面的代碼

<code>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)/<code>

運行結果如下

<code>Yes
33
33
50
50/<code>

上述我們就更改了原表的行為方法

__index

當我們訪問表中的一個元素不存在時,則會去尋找 __index 元方法,如果存在則會返回結果,否則返回nil

<code>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)/<code>

運行結果如下

<code>YuanBo
100
Other/<code>

__newindex

當給你的表中不存在的key進行賦值時,lua解釋器則會尋找__newindex 元方法,發現存在該方法,則執行該方法進行賦值,通過rawset來進行賦值操作

<code>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)/<code>

輸出Yuan Bo

rawget和rawset

rawget是為了繞過__index而出現的,還是上面的代碼

<code>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))/<code>

輸出的nil
針對rawset,如果我們上面代碼這麼寫

<code>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)/<code>

此時輸出了nil,如果__newindex裡面這樣的呢?

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

則會報如下錯誤

<code>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/<code>

__index 和 __newindex的區別,__index是直接取表的值,沒有對應的key,則根據__index返回,__newindex主要用於表不存在的key的賦值操作。


分享到:


相關文章: