example1
Account = {balance = 0}
function Account:new(conf)
conf = conf or {}
setmetatable(conf,self)
self.__index = self
return conf
end
-
Account
模擬一個對象,new
方法類似於實例化一個對象,conf
可存放一些初始值作用等同於conf
是Account
的子類。 -
解釋:
Account
這個table有一個屬性balance
,通過new
函數實例化一個類繼承於Account
。在lua中類,父類都是通過table數據結構加上元表元方法來實現。
__index
是lua一個元方法,被廣泛的使用在模擬實現繼承方法。訪問一個table中不存在的key,lua將會返回一個nil。
但一個表存在元表的時可能會發生改變。既訪問不存在的key時,如果這個table存在元表,就會嘗試在它的元表中尋找是否存在匹配key對應的value。 -
:
是lua面向對象的語法糖。Account:new(conf)
等同於Account.new(self, conf)
,相當於將調用者自身當做第一個參數,使用冒號調用就相當於隱式地傳遞self
參數。 -
元方法的定義可以寫在new函數外面。如下:
Account = {balance = 222}
Account.__index = Account
function Account:new(conf)
conf = conf or {}
setmetatable(conf, self)
return conf
end
或者類似於lua_resty_mysql中寫法:
Account = {balance = 222}
local mt = {__index = Account}
function Account:new(conf)
conf = conf or {}
setmetatable(conf, mt)
return conf
end
- 調用:
local aa = Account:new()
ngx.say(aa.balance) --222
example2
local a = {}
local b = {k = 11}
setmetatable(a,b) --設置元表,僅僅設置元表並不能使lua尋找父類的方法或屬性
b.__index = b --設置元方法
b.v = 22 --給b表增加一個屬性
a.aa = 33 --給a表增加一個屬性
print(a.k) --11, 返回父類b中k的值。
print(a.v) --22,父類增加的屬性和方法都可以被子類繼承
print(b.aa) --nil,相反,父類並不可以獲取子類的值
_call 索引, 它允許你把表當函數調用
local t = setmetatable({}, {
__call = function(t, a, b, c, d)
return (a + b + c) * d
end
})
local res = t(1,2,3,4) --24