Lua學習之元表

2021-10-12 03:04:25 字數 3624 閱讀 6980

在 lua table 中我們可以訪問對應的key來得到value值,但是卻無法對兩個 table 進行操作。因此 lua 提供了元表(metatable),允許我們改變table的行為,lua中的每個值都可以用乙個metatable來表示,每個行為則關聯了對應的元方法。

元表的處理有兩個很重要的函式:

setmetatable(table,metatable): 對指定 table 設定元表(metatable),如果元表(metatable)中存在 __metatable 鍵值,setmetatable 會失敗。

getmetatable(table): 返回物件的元表(metatable)。

使用getmetatable來獲取乙個table或userdata型別變數的元表,當建立新的table變數時,使用getmetatable去獲取元表,將返回nil;同樣的,我們也可以通過使用setmetatable去設定乙個table或userdata型別變數的元表。

注:lua在建立新的table時不會建立元表,lua**中只能設定table的元表。

例1:

local   t=

print(getmetatable(t))

輸出結果:

nil
例2:

local   t=

print(getmetatable(t))

local t1={}

setmetatable(t,t1)

assert(getmetatable(t)==t1)

print(getmetatable("hello world"))

print(getmetatable(10))

輸出結果:

nil

table: 0xfb9e40

nil

如何對指定的表設定元表例項:

mytable = {}                          -- 普通表

mymetatable = {} -- 元表

setmetatable(mytable,mymetatable) -- 把 mymetatable 設為 mytable 的元表

以上**也可以直接寫成一行:

mytable = setmetatable({},{})
返回物件元表:

getmetatable(mytable)                 -- 返回mymetatable
當我們訪問乙個table中不存在的字段時,預設情況下,得到的結果是nil,但是這種情況很容易被改變,lua是按照以下步驟決定是返回nil還是其他值:

1.當訪問乙個table的字段時,如果table有這個字段,則直接返回對應的值。

2.通過鍵來訪問 table 的時候,如果這個鍵沒有值,那麼lua就會尋找該table的metatable(假定有metatable)中的__index 鍵。如果__index包含乙個**,lua會在**中查詢相應的鍵。如果__index包含乙個函式的話,lua就會呼叫那個函式,table和鍵會作為引數傳遞給函式。

3.呼叫__index 元方法檢視表中元素是否存在,如果不存在,返回結果為 nil;如果存在則由 __index 返回結果。

注:__index元方法不必一定是乙個函式,也可以是乙個table.

例1:

mytable = setmetatable(, )

print(mytable.key1,mytable.key2)

輸出結果:

value1    metatablevalue
例項解析:

1.mytable 表賦值為 。

2.mytable 設定了元表,元方法為 __index。

3.在mytable表中查詢 key1,如果找到,返回該元素,找不到則繼續。

4.在mytable表中查詢 key2,如果找到,返回 metatablevalue,找不到則繼續。

5.判斷元表有沒有__index方法,如果__index方法是乙個函式,則呼叫該函式。

6.元方法中檢視是否傳入 "key2" 鍵的引數(mytable.key2已設定),如果傳入 "key2" 引數返回 "metatablevalue",否則返回 mytable 對應的鍵值。

以上**也可簡單寫成:

mytable = setmetatable(,  })

print(mytable.key1,mytable.key2)

__newindex元方法與__index類似,__newindex 元方法用於更新table中的資料,__index用於查詢table中的資料。

1.當你給表乙個缺少的索引賦值時,lua直譯器會先判斷這個table是否有元表

2.如果沒有元表,則直接新增這個索引,進行對應的賦值。如果有元表,則查詢元表中是否有__newindex 元方法。

3.如果有這個__newindex元方法,lua直譯器執行呼叫這個函式而不進行賦值操作。

4.如果這個__newindex對應的不是乙個函式,而是乙個table時,lua直譯器就在這個table中執行賦值,而不是對原來的table執行操作。

例1:

mymetatable = {}

mytable = setmetatable(, )

print(mytable.key1)

mytable.newkey = "新值2"

print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "新值1"

print(mytable.key1,mymetatable.key1)

輸出結果:

value1

nil 新值2

新值1 nil

例項解析:

1.表設定了元方法 __newindex

2.在對新索引鍵(newkey)賦值時(mytable.newkey = "新值2"),會呼叫元方法,而不進行賦值。

3.對已存在的索引鍵(key1),會進行賦值,而不呼叫元方法 __newindex。

例2:

local  tb1={}

local tb2={}

tb1.__newindex=tb2

tb2.__newindex=tb1

setmetatable(tb1,tb2)

setmetatable(tb2,tb1)

tb1.x=5

輸出結果:

/usr/local/lua-5.3.5/lua53: script.lua:10: '__newindex' chain too long; possible loop

stack traceback:

script.lua:10: in main chunk

[c]: in ?

exited with error status 1

Lua 基礎之元表

print getmetatable hello 003e7050 print getmetatable lua 003e7050 print getmetatable 12 nil print getmetatable nil t print getmetatable t nil setmetat...

Lua語言學習之元表與元方法

元表與元方法 在學習table的時候已經提到這兩個概念。其實,可以把這兩個概念和c 中的運算子過載進行比較,在功能上確有相似性。例如,c 中自定義的型別不能進行數 算,但是我們可以過載運算子就可以 進行數 算操作。lua中就是用元表和元方法來實現這個功能的。lua中的 table 都可以有元表,我們...

Lua基礎之元表(metatable)

lua中的元表允許我們通過乙個tablea特殊的鍵值自定義另乙個tableb的行為,這些特殊的鍵值稱為元方法,tablea則稱為tableb的元表。函式 描述 index 呼叫乙個索引 newindex 給乙個索引賦值 add 運算子 sub 運算子 mul 運算子 div 運算子 mod 運算子 ...