lua學習(二)元表

2021-10-23 11:31:26 字數 4087 閱讀 4831

本文大量參考openresty最佳實踐以及lua元表詳解

-->>>>>>>>>>>>>>>> 元表

-- 元表是用來定義table或userdata操作方式的表,可以用來實現物件導向

-- 元表的設定

-- 定義元表

local t1 =

local t2 =

local mt =

-- 定義元表mt.__add元方法

mt.__add =

function

(t1,t2)

local temp =

for _,v in

pairs

(t1)

do table.

insert

(temp,v)

endfor _,v in

pairs

(t2)

do table.

insert

(temp,v)

endreturn temp

end-- 設定t1的元表為mt

setmetatable

(t1,mt)

local t3 = t1+t2 --> 實際上t3 = t2+t1也是可以的。編譯器會檢視t1是否有元表,並檢視t1的元表是否有__add元方法,若有則呼叫;檢視t2是否有元表,並檢視t2的元表是否有__add元方法,若有則呼叫

-- 輸出t3

local st =

""print

(st)

--結果

---- 實際上還可以對__add元方法進行過載,過載的第乙個引數時self,但是這裡的過載導致之後的__call方法如果不重新使用setmetatable(t1,mt)會報錯,如果不過載就不會,

local union =

function

(self,another)

local temp =

for _,v in

pairs

(another)

do table.

insert

(temp,v)

endfor _,v in

pairs

(self)

do table.

insert

(temp,v)

endreturn temp

endsetmetatable

(t1,

)local t4 = t1+t2

local st =

""print

(st)

--結果:

---- 定義__call可以讓table當做乙個函式來使用

mt.__call =

function

(mytable,

...)

-- 輸出所有的引數

for _,v in

ipairs

doprint

(v)end

endsetmetatable

(t1,mt)t1(

1,2,

3)--結果

--1--2

--3-- 修改__tostring可以修改table轉化為字串的行為

print

(t1)

mt.__tostring =

function

(t)local s =

"}"return s

endprint

(t1)

--結果:

--table: 0x000cbc80

--}-- 當呼叫到table乙個不存在的索引是,會使用到元表的__index元方法,和之前方法不一樣的是,__index既可以是函式也可以是table

print

(t1.key)

mt.__index =

function

(t,key)

return

"it is "

..key

endprint

(t1.key)

mt.__index =

print

(t1.key)

print

(t1.key2)

--結果:

--nil

--it is key

--it is a beautiful key

--nil

--當為table中乙個不存在的索引賦值時,會呼叫元表中的__newindex元方法

mt.__newindex =

function

(t,index,value)

print

("index is "

..index)

print

("value is "

..value)

endt1 =

setmetatable

(t1,mt)

--> 此時的t1已經屬於新建立的t1,因此需要重新設定元表

print

(t1.key)

t1.newkey =

10--> 實際中表的newkey索引值還是為空,上面只是呼叫了元表的__newindex方法,輸出了引數資訊

print

(t1.newkey)

--結果:

--it is a hello key

--index is newkey

--value is 10

--nil

--在__neweindex作為乙個table時,為不存在的索引賦值會導致該索引和賦值被賦到__newindex所指向的表中,不會對原來的表進行修改

local newtable =

mt.__newindex = newtable

t1 =

setmetatable

(t1,mt)

print

(t1.newkey,newtable.newkey)

t1.newkey =

"it is a hello kitty"

print

(t1.newkey,newtable.newkey)

--結果:

--nil nil

--nil it is a hello kitty

-- rawget以及rawset可以直接獲取表中索引的實際值,並進行賦值,而不受元方法影響

mt.__index =

t1 =

setmetatable

(t1,mt)

print

(t1.key)

--通過rawget可以直接獲取t中的key索引,不受__index元方法的影響

print

(rawget

(t1,

"key"))

--結果:

--it is hhkey

--nil

--rawset可以直接為表中索引賦值,而不通過元表的__newindex元方法

local newtable =

mt.__newindex = newtable

t1 =

setmetatable

(t1,mt)

print

(t1.newkey,newtable.newkey)

rawset

(t1,

"newkey"

,"it is 233key"

)print

(t1.newkey,newtable.newkey)

--結果:

--nil nil

--it is 233key nil

-- 如果想保護物件對其使用者既看不到也不能修改metatables,

-- 我們可以對metatable設定__metatable的值,getmetatable將會返回這個值,而呼叫setmetatable將會出錯

local t1 =

setmetatable(,

)print

(getmetatable

(t1)

)-- setmetatable(t1,{}) -- 此時該語句會引發編譯器報錯

Lua學習之元表

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

C 中二元函式物件和二元謂詞

在c stl演算法中,在演算法的輸入和輸出中,一定要分清是函式物件,還是謂詞,還是迭代器。具體看如下 注意看注釋 includeusing namespace std include string include include include include include 二元函式物件 temp...

python選擇排序二元選擇 二元選擇排序

注 本題只需要提交標記為修改部分之間的 c 語言方式。二元選擇排序 對傳統的選擇排序演算法改進,在一趟比較過程中,同時記錄最大值和最小值位置,將最小值與第乙個元素交換,最大值與最後乙個元素交換,即一趟比較確定兩個元素,對剩下的序列重複上述過程,直至序列為空。include using namespa...