Lua实现switch的一种方案
欢迎前往个人博客 驽马点滴 和视频空间 哔哩哔哩-《挨踢日志》
if ... elseif ... end 形式
local ET_CASE_ONE = 1
local ET_CASE_TWO = 2
local function do_case_one( ... )
print("do_case_one")
end
local function do_case_two( ... )
print("do_case_two")
end
local function do_default()
print("do_default")
end
function switch(case)
if case == ET_CASE_ONE then
do_case_one()
elseif case == ET_CASE_TWO then
do_case_two()
else
do_default()
end
end
但是这种形式判断的效率是比较低下的, 对于每一个case, 最坏的情况是要判断所有的可能,然后进到 do_default, 因此有这样的改进:
使用table表, 将每种可能的情况作为key
local CONST_ET_CALSE_HANDLE_FUNC_LIST = {
[ET_CASE_ONE] = do_case_one,
[ET_CASE_TWO] = do_case_two,
}
function switch(case)
if CONST_ET_CALSE_HANDLE_FUNC_LIST[case] then
return CONST_ET_CALSE_HANDLE_FUNC_LIST[case]()
else
return do_default()
end
end
但是这样会很不舒服, 因为操作函数一部分写在了操作函数表中,而default部分却要写在switch函数中,这样导致业务逻辑维护的不集中,超级不爽的,是吧!
因此,我们希望,在表中找不到对应的case时,能够返回default处理函数
更加合理的解决方案
local CONST_ET_CALSE_HANDLE_FUNC_LIST = {
[ET_CASE_ONE] = do_case_one,
[ET_CASE_TWO] = do_case_two,
__default = do_default,
}
SWITCH_METATABLE = {
__index = function(t, k)
return rawget(t, "__default")
end,
}
setmetatable(CONST_ET_CALSE_HANDLE_FUNC_LIST, SWITCH_METATABLE)
function switch(case)
return CONST_ET_CALSE_HANDLE_FUNC_LIST[case]()
end
这个要求有这样的前提: 表的__default必须持有一个function类型的值.
整理
local SWITCH_METATABLE = {
__index = function(t, k)
return rawget(t, "__default")
end,
}
function SwitchGenerator(tbl)
tbl = tbl or {}
setmetatable(tbl, SWITCH_METATABLE)
return function(case)
return tbl[case]()
end, tbl
end
function test()
local ET_CASE_ONE = 1
local ET_CASE_TWO = 2
local function do_case_one( ... )
print("do_case_one")
end
local function do_case_two( ... )
print("do_case_two")
end
local function do_default()
print("do_default")
end
local switch, tbl = SwitchGenerator({
[ET_CASE_ONE] = do_case_one,
[ET_CASE_TWO] = do_case_two,
__default = do_default,
})
local function realTest()
for i=1,3 do
switch(i)
end
end
realTest()
tbl[3] = function() print("new add case") end
realTest()
end
test()
欢迎前往个人博客 驽马点滴 和视频空间 哔哩哔哩-《挨踢日志》