本文大量參考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...