關於Lua重要的元方法__index 和__newindex
元表和元方法是lua進行面向物件程式設計的很重要的方法,所以 花時間研究了一下。
__index方法(主要是查詢時)
當呼叫一個table的索引值不存在時,lua會查詢該table的__index方法,__index方法可以是函式,也可是一個table;
舉例:
local mt = {}
一 、--__index傳入的是函式
mt.__index = function (table,key)
print("key = ",key)
end
local t = {my = "i have one"}
print("這是輸出1",t.myAdd)
--[LUA-print] 這是輸出1 nil
setmetatable(t,mt)
print("這是輸出2",t.myAdd)
--[LUA-print] key = myAdd --這句列印說明 程式進入了__index方法中查詢 --[LUA-print] 這是輸出2 nil -- 但是__index方法中還是沒有這個索引值
二 、-- __index 傳入的是table
local mt = {}
local mtTable = { meta = "this is prevalue"}
mt.__index = mtTable
local t = {my = "i have one"}
print("這是輸出1",t.meta) --[LUA-print] 這是輸出1 nil (普通查詢key不存在 列印為空)
setmetatable(t,mt)
print("這是輸出2",t.meta)--[LUA-print] 這是輸出2 this is prevalue (設定元表後,對於不存在的key進入元表查詢,元表中返的table有於是輸出)
__newindex元方法(主要是賦值時)
當給table中不存在的索引賦值時,Lua會去查詢該table的__newindex方法。__newindex同樣可以傳入函式 和 一個table
舉例:
一 、--__newindex傳入的是函式
local mt = {}
mt.__newindex = function (table,key,value)
print("key值是:",key)
print("value值是:",value)
end
local t = {aa = "hehe"}
setmetatable(t,mt)
print(t.aa)
--輸出表中已有的索引aa
[LUA-print] hehe ----- 只有一句列印,沒有進入元方法中,因為t中有aa索引
--為表中不存在的索引進行賦值
t.bb = "wawa"
print(t.bb)
[LUA-print] key值是: bb [LUA-print] value值是: wawa
-- 上面兩句列印說明進入到了元方法,並且列印了索引 和值
[LUA-print] nil -- 這句列印非常重要,可以發現t.bb還是空值,說明上面的賦值操作並沒有起作用,因為只是進入了元表中,但元表沒有進行賦值,所以列印還是nil
--列印完整的t
printt(t)
[LUA-print] ["aa"] = "hehe", -- 從這個列印可以看出,t 現在還是隻有一個索引,並沒有賦值成功。
二、--__newindex傳入的是table
local mt = {}
local mtTable = {}
mt.__newindex = mtTable
local t = {}
setmetatable(t,mt)
print(t.newkey,mt.newkey)
[LUA-print] nil nil
因為兩個t都是空 所以列印都是nil
-- 這裡給 t 新增索引並賦值
t.newkey = "this is new value"
print(t.newkey,mtTable.newkey)
[LUA-print] nil this is new value
但是列印的結果是 t 並沒有賦值成功 反而是mtTable賦值成功。
這是因為給 table 不存在的索引賦值時,進入了他的 元方法,而在元方法中的table 就有了這個鍵值對。
而原先的 t 則 不會受影響。