腳本小子_Lua元表例子

一、Lua元表例子
1、table的__index例子解析
1.1、__index例子1
  • 代碼
local t = {'a','b'}
-- 打印t所具有的key
print(t[1])
print(t[2])
-- 打印t所具不具有的key
print(t[3])

-- 設置t __index
setmetatable(t,{__index = function(t,k)
for k,v in pairs(t) do
print(k,'=',v)
end
print(k)
end
})
print(t[3])
  • 解析過程:
    • 程序從上往下執行,遇到print函數,分別打印'a','b'。因爲table t沒有索引3的值,所以打印nil
    • 設置table t的__index屬性元表
    • 打印t[3],lua先檢查t是否存在,如存在則直接返回對應的值。相反則檢查t是否設置__index,如無則返回nil
如有,則根據__index所設置的值進行處理,當前該值爲一個函數,因此就回調該函數,該函數接收兩個參數,一個值table本身,另一個是索引值。
1.2、__index例子2
  • 代碼
local t = {'a','b','c'}
local m = {}
setmetatable(t,m)
-- print(getmetatable(t) == m)
m.__index = function(t,k)
for k,v in pairs(t) do
print(k,'=',v)
end
print(k)
end
print(t[4])
  • 解析過程
    • 根據setmetatable的參數格式,單獨定義了一個table,獲取的值則根據上面的說明執行
1.3、__index例子3
  • 代碼
local t = {'a','b','c'}
setmetatable(t,{
__index = function(t,k)
for k,v in pairs(t) do
print(k,'=',v)
end
print(k)
end
})
local t1 = {x=1,y=2}
setmetatable(t1,{__index=t})
print(t1.x)
print(t1[1])
  • 解析過程
    • 從這幾個例子可以看出,__index元方法不一定是函數,它還可以是table類型。當其是函數時,則lua將table和索引k作爲參數來調用該函數。而當它是table時,lua則以相同的方式來重新訪問這個table
2、table __newindex例子
2.1、__newindex例子1
  • 代碼
local t = {'a','b'}
setmetatable(t,{
__index = function(t,v)
print(k)
end,
__newindex = function(t,k,v)
t[k] = v
print(k,v)
end
})
print(t[2])
t[2] = 'c'
print(t[2])
t[3] = 'c'
  • 解析過程
    • 程序運行出錯。原因是table設置了__newindex,因此在回調函數中執行t[k]=v,時又回調__newindex,從而進入死循環
2.2、__newindex例子2
  • 代碼
local t = {'a','b'}
setmetatable(t,{
__index = function(t,v)
print(k)
end,
__newindex = function(t,k,v)
rawset(t,k,v)
end
})
print(t[2])
t[2] = 'c'
print(t[2])
t[3] = 'c'
for k,v in pairs(t) do
print(k,'=',v)
end
  • 解析過程
    • 當程序執行t[3]='c'時,由於t中不存在索引3,因此觸發__newindex元方法。傳入三個參數,t本身、新的索引k,和其對應的值v。再執行rawset,對t本身賦值。就可以確保不會死循環調用__newindex
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章