1. 程式人生 > >[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方案

Lua實現switch的一種方案 if ... elseif ... end 形式 local ET_CASE_ONE = 1 local ET_CASE_TWO = 2 local function do_case_one( ... ) print("do_case

利用Unity3D與Oculus實現機器情緒安撫師的方案

(一張最原始的Unity3D中音樂視覺化粒子海的圖,想象一下,如果這幅場景出現在虛擬裝置中,輔以根據音樂頻譜變化的色彩與悅動頻率,會是怎樣的效果呢?)     Unity3D有著非常完備的虛擬三維場景互動開發功能,以Oculus為代表的虛擬現實裝置又有著極強的視覺感染力,一副不錯的耳機可以產生身臨其境的聽覺

關於實現log4j2日誌脫敏的方案

情景 最近公司嚴格要求日誌脫敏,對於敏感欄位,諸如身份證號、手機號、銀行卡號等使用者資訊進行掩碼,保證日誌中沒有明文。 專案程式碼中列印日誌的地方形如: logger.info("idCard:{},phone:{},mobile:{},name:{}

實現VUE2.0中props資料雙向繫結的方案

問題描述 在vue2.0中,我們通過props方法來接受父元件所傳過來的值,但是這個過程是單項的,父元件可以改變傳給子元件的值,但是如果子元件想改變所接受的值並傳給父元件是不可以的,會報以下的錯誤。 該錯誤的意思的是:避免直接更改一個PROP,因為每當父元件重新呈現時

實現資料邏輯刪除的方案

## 什麼是邏輯刪除 所謂邏輯刪除是指資料已經“不需要”了,但是並沒有使用delete語句將這些資料真實的從資料庫中刪除,而只是用一個標誌位將其設定為已經刪除。 ![](https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3340871784

多域名環境,頁面獲取url的方案

loadurl -i 頁面獲取url html 變量 ice content 一個 信息 因為系統是分布式部署的。而且有多個域名,所以常常涉及到獲取url的問題。這是系統框架層面須要提供的能力。否則每一個模塊都須要自己去想辦法獲取ip,就會非常混亂。上線也easy發生b

利用Guzzle實現PHP異步發送郵件(laravel5.4)

dot 博文 接下來 lar 時間 重點 5.4 targe 占用 前言:第二種實現方法 方法的思路: 此方法的實現需要借助Guzzle這個PHP的HTTP客戶端,用來輕而易舉地發送請求,並集成到我們的WEB服務上(laravel中如何引入guzzle不多說) 使用該方

集群應用Session一致性實現的三方案

tar lan cnblogs htm ever ref blank post .cn 轉自:http://blog.csdn.net/zwx521515/article/details/78679679    https://www.cnblogs.com/study-e

[golang]讓golang支援泛型程式設計的方案

本部落格原創博文版權所有 @[email protected] 僅供交流學習使用用於商業用途請聯絡原作者  轉載請註明出處:http://blog.sina.com.cn/a

lua實現switch和快速排序

lua實現switch和快速排序 快速排序 switch 快速排序 local list = {.....} local comparefuc = function (a, b) return a

AI實現的兩方案,暴力推演與因果率

AI實現的兩種方案,暴力推演與因果率 學習PYTHON兩個月,寫個小遊戲練手。也為以後找工作做儲備。 從最簡單的九格棋入手。 九格棋玩法簡單,橫向,縱向,斜向三子連線則為勝。 基本設計構件有: 一、GUI介面。 介面我選用PYGAME做的。因為PYGAME中沒有提供按鈕等相關控制

叢集應用Session一致性實現的三方案

1. 為什麼會有Session? · HTTP 協議本身是無狀態的,這與HTTP協議本來的目的是相符的,客戶端只需要簡單的向伺服器請求下載某些檔案,無論是客戶端還是伺服器都沒有必要紀錄彼此過去的行為,每一次請求之間都是獨立的,好比一個顧客和一個自動售貨機或者一個普通的(非會

C、C++實現智慧資料管理架構

之前研究STL相關結構的時候,發現STL系列的map、list、vector等設計有以下缺陷: 1.迭代刪除節點的情況下只可以刪除一個節點(不包括清除所有節點的情況); 2.在多執行緒情況下需要加鎖或臨界區等形式同步物件結構資訊,這種情況屬於當前大部分系統設計的

用QT產生報告的方案

------------------------------------------------------------------------------------------------ (1)有一個xml檔案作為報告的模板F,各種需要動態顯示的資料在模板中有唯一的標識,執行時可以根據這些標識來獲得實際

Android客戶端和伺服器交換資料的方案

由於很多因素使得客戶端和伺服器之間互動的一些資料都要經過加密,為了方便,很多使用非對稱的加密演算法進行加密,其中RSA演算法成為首選。下面說說在Android客戶端怎中怎麼應用這種加密方案。 首先在我們Android客戶端啟動應用程式的時候,我們先請求一個伺服器,讓服務將R

Libgdx中如何繪製帶透明度的3D模型相關實現程式碼 2方案

問題?如何解決在繪製帶透明度的3D模型時候,深度和透明度混合之間的矛盾問題。 第一種方法: 採取透明度測試,在glsl裡面,先開啟透明度測試只通過不透明的部分,然後再繪製繪製透明的部分即可。 public void draw (Batch batch, float pa

Android 本地HTML螢幕適配的方案

前言:在Android開發中WebView載入網頁,網頁的適配應該是前端來處理的,畢竟客戶端的對網頁的控制是有限的。但是如果有一個本地的網頁而且該網頁的body是固定寬度的,讓我們去適配所有裝置還是比較頭疼的,當然這種應用場景是很罕見的,儘管如此我們還是討論

成員函式指標,C++模板 和command設計模式結合實現命令處理方式

template<class Receiver>class SimpleCommand : public Command{public:typedef void (Receiver::*Action)();    SimpleCommand(Receiver* r, Action a) : _re

PHP連線池實現想法

雖然現在名義上是PHP開發,不過做這資料分析的事,平時工作大部分用的是JAVA。C語言出身,學的語言比較多,JAVA還算熟悉,不過之前一直都沒用連線池。第一次遇到連線池是在學校的時候女朋友用連線池出現問題了,找我,我看了下覺得沒必要,直接就刪了。那時候用的是第三方擴充套件,

poj 2409 Let it Bead 串由n個珠子組成的項鍊用c顏色染,旋轉/翻轉算方案,問共有多少不同的染色方案

  #include <cstdio> const int mod=1000000007; int fun(int a,int n) {     if(n==1) return a%mod;     if(n==0) return 1;     long lon