於Delphi的Case述句中使用字串當(dāng)作判別變數(shù)
● 前言
提到Case述句(statement),我們首先會(huì)聯(lián)想到的應(yīng)用案例莫過(guò)於就是透過(guò)一個(gè)判別變數(shù),讓程式流程依照不同的條件狀況來(lái)選擇符合的路徑繼續(xù)執(zhí)行下去。或者是,當(dāng)我們的程式中出現(xiàn)了一連串的if與 else if述句組合時(shí),我們也經(jīng)常都會(huì)想到要利用Case述句來(lái)簡(jiǎn)化程式碼並藉以提升其可讀性與執(zhí)行效率。
但是在某些情況下,Case述句並無(wú)法應(yīng)用於我們的程式當(dāng)中,因?yàn)槠渌试S接受的判別變數(shù)僅限於任何形式的咚閌劍╡x
PRession)與序數(shù)型別(ordinal type),這所謂的「序數(shù)型別」指的就是整數(shù)、字元、列舉、布林和集合等「有次序」的,而且可以應(yīng)用於諸如Ord()、Pred()、Succ()、Low()與High()等函示的型別(請(qǐng)參閱[1])。
不幸的是,字串(string)顯然並非序數(shù)型別的一種,而在某些時(shí)候(底下馬上會(huì)舉例),當(dāng)條件變數(shù)的型別是字串而且條件分支又相當(dāng)多時(shí),儘管無(wú)奈,然而除了使用大量的if與else if述句之外,似乎也別無(wú)他法了,唉。
例如下面的程式碼在Delphi中便不被允許:
#001 var
#002 Str: String; // 宣告String型別的判別變數(shù)
#003 begin
#004 case Str of // 錯(cuò)誤訊息: Ordinal type required
#005 // ...
#006 end;
#007 end;
這根本就無(wú)法通過(guò)編譯嘛,因此傳統(tǒng)的解決方案通常是將之轉(zhuǎn)換為大量的if與else if述句的組合體。此時(shí)真希望我們用的是Visual Basic,因?yàn)橄旅娴某淌酱a是可被其編譯器允許的(請(qǐng)參閱[5]):
#001 Dim Str As String ' 宣告String型別的判別變數(shù)
#002 Select Case Str ' 等同於Delphi的Case述句
#003 '...
#004 End Select ' OK, 通過(guò)編譯
於是在本文中,筆者試圖以此問(wèn)題為出發(fā)點(diǎn),在「除了轉(zhuǎn)換為if與else if述句組合的傳統(tǒng)解決方案之外」找尋其他可行的因應(yīng)之道,並由衷地希望本文對(duì)於面臨此問(wèn)題而亟欲尋求解決方法的人(看了[12]-[14]之後,筆者更發(fā)現(xiàn)確實(shí)如此)能夠有所幫助。
先預(yù)告一下好了,筆者打算介紹7種解決方案,其中前5種方法乃是節(jié)錄或延伸自[9]-[13]的內(nèi)容,而第6種則是筆者實(shí)作的綜合性多載化(overloading)版本。這些方案分別是:
v 方案一:搜尋字串陣列
v 方案二:使用實(shí)數(shù)索引
v 方案三:利用雜湊函數(shù)
v 方案四:巢套case述句
v 方案五:使用TStringList
v 方案六:實(shí)作多載函示
v 方案七:應(yīng)用現(xiàn)成函示
本文將從複習(xí)條件述句(內(nèi)容主要參考[1]與[4])與認(rèn)識(shí)字串(內(nèi)容主要參考[2])等主題開始,熟悉Delphi者可略過(guò)此部分,直接閱讀〈效能議題〉小節(jié)直到文末為止