首页 > 代码库 > [Lua]实现switch的一种方案

[Lua]实现switch的一种方案

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()


技术分享


[Lua]实现switch的一种方案