1. 程式人生 > >關於Lua重要的元方法__index 和__newindex

關於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 則 不會受影響。

注意 :要避開元方法 避免在取值 和賦值時觸發 __index 和__newindex 可以使用  rawget (table,key)  得到指定的索引值 。 以及 rawset(table,key),給指定索引賦值