Lua 入門學習教程(二) 函式 與 回撥函式
阿新 • • 發佈:2019-01-08
還記得開始學C語言的時候,書上就拿兩個數相加 作為例子,來介紹函式。我也拿 Add 來說吧。
函式的簡單寫法就像下面的Add
local function Add( a,b )
-- body
print(a+b)
end
Add(10,20)
然後面向物件
local MathTools={}
function MathTools:Add( a,b )
-- body
print(a+b)
end
MathTools.Add(self,10,20)
MathTools:Add(10,20)
如果使用 點 來呼叫函式,第一個引數必須是 self ,self的作用是指明函式作用與誰。
如果使用冒號 來呼叫函式,就可以省略self,這是語法糖。
回撥函式 通過遊戲中的網路訊息分發來說吧
比如我遊戲中有一個 NetMsgDispatcher.lua,作為被監聽者存在。遊戲的各個模組觀察者 在一開始會註冊回撥函式。
有兩種解決方法
1、使用匿名函式,像下面這麼寫。
--NetMsgDispatcher.lua local NetMsgDispatcher= { m_NetMsgCallbackTable={} } --註冊 function NetMsgDispatcher:RegisterNetMsgCallback(msgindex,callback) -- body if(self.m_NetMsgCallbackTable[msgindex]==nil) then local callbackTable={} table.insert(self.m_NetMsgCallbackTable,msgindex,callbackTable) end local callbackTable = self.m_NetMsgCallbackTable[msgindex] table.insert(callbackTable,callback) end --分發 function NetMsgDispatcher:DispatchMsg(cmdIndex) -- body for key,value in pairs(self.m_NetMsgCallbackTable) do if(key == cmdIndex) then --輸出callbackTable for callbackkey,callbackvalue in pairs(value) do --print("..." .. callbackkey,callbackvalue) callbackvalue() --回撥; end end end end return NetMsgDispatcher
測試程式碼
local GameInstance= { m_name="123" } local NetMsgDispatcher = require("NetMsgDispatcher") print("GameInstance Start") function GameInstance:Start() -- body NetMsgDispatcher:RegisterNetMsgCallback(1001,function() -- body self:callback1001() end) NetMsgDispatcher:DispatchMsg(1001) end function GameInstance:callback1001() -- body print("1001callback=" .. self.m_name) end GameInstance:Start() return GameInstance
2、註冊回撥函式的時候,把 self 也一起註冊進去
--**************************
-- 檔名:NetMsgDispatcher.lua
-- 檔案描述:NetMsgDispatcher
-- 建立日期:2015/11/15
-- Author:Create by 陳鵬
--**************************
local NetMsgDispatcher=
{
m_NetMsgCallbackTable={}
}
--註冊原樣返回的
function NetMsgDispatcher:RegisterNetMsgBackCallback(msgindex,this,callback)
self:RegisterNetMsgCallback(msgindex,this,callback)
end
--註冊返回的
function NetMsgDispatcher:RegisterNetMsgCallback(msgindex,this,callback)
-- body
if(self.m_NetMsgCallbackTable[msgindex]==nil) then
--msgindex對應的table,裡面放handler
local callbackTable={}
--把 callbackTable 新增到 m_NetMsgCallbackTable
table.insert(self.m_NetMsgCallbackTable,msgindex,callbackTable)
end
local callbackTable = self.m_NetMsgCallbackTable[msgindex]
table.insert(callbackTable,{m_this=this;m_callback=callback})
end
--反註冊原樣返回的
function NetMsgDispatcher:UnRegisterNetMsgBackCallback(msgindex,callback)
self:UnRegisterNetMsgBackCallback(msgindex,callback)
end
--反註冊返回
function NetMsgDispatcher:UnRegisterNetMsgCallback(msgindex,callback)
if self.m_NetMsgCallbackTable[msgindex]~=nil then
local callbackTable = self.m_NetMsgCallbackTable[msgindex]
for index=1,table.maxn(callbackTable),1 do
if callbackTable[index].m_callback==callback then
callbackTable[index]=nil
table.remove(callbackTable,index)
break
end
end
else
Debug.LogError(tostring(msgindex) .. "has not Register!!donot UnRegister!")
end
end
--分發
function NetMsgDispatcher:DispatchMsg(cmdIndex)
-- body
for key,value in pairs(self.m_NetMsgCallbackTable) do
if(key == cmdIndex) then
for callbackkey,callbackvalue in pairs(value) do
callbackvalue.m_callback(callbackvalue.m_this) --回撥;
end
end
end
end
return NetMsgDispatcher
測試程式碼
local GameInstance=
{
m_name="123"
}
local NetMsgDispatcher = require("NetMsgDispatcher")
print("GameInstance Start")
function GameInstance:Start()
-- body
NetMsgDispatcher:RegisterNetMsgCallback(1001,self,self.callback1001)
NetMsgDispatcher:DispatchMsg(1001)
end
function GameInstance:callback1001()
-- body
print("1001callback=" .. self.m_name)
end
GameInstance:Start()
return GameInstance
總之遵循一個原理:
如果使用 點 來呼叫函式,第一個引數必須是 self ,self的作用是指明函式作用與誰。回撥函式也是如此!
如果使用冒號 來呼叫函式,就可以省略self,這是語法糖。