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, 因此有这样的改进:
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
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()
原文地址:http://blog.csdn.net/humanxing/article/details/42318213