Delphi在case語句中使用字符串

Delphi在case語句中使用字符串

在case語句中使用字符串   
(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
在 case 語句中使用字符串 --- by 熊恆(beta)

我今天要介紹的是一個比較另類的方法。大家都知道,case 語句只能對順序類型
            (ordinal type)管用,那麼我們先看一下順序類型到底有那些呢:1)整型;2)字
            符型;3)枚舉型。
            於是也就演化出三種在 case 語句裏面使用字符串的方法(耐心看下去哦,最後一
            種方法纔是今天的重點:-p):

假如我們的具體應用如下(理想的,但是錯誤的寫法):

str := 'Chongqing';
            case str of // 編譯器將在這一行制止你 :-(
            'Beijing': ShowMessage('First');
            'Tianjing': ShowMessage('Second');
            'Shanghai': ShowMessage('Third');
            'Chongqing': ShowMessage('Forth');
            else ShowMessage('Other');
            end;

(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
法一:字符串轉爲整型
            這應該是比較通行的方法了,主要是利用 TStringList。先把備選的字符串挨個
Add 進去,然後調用其 IndexOf 方法。該方法返回一個整數,表示待找字符串出
            現在列表中的位置:

//var strList: TStringList;

strList := TStringList.Create;
            strList.Add('Beijing');
            strList.Add('Tianjing');
            strList.Add('Shanghai');
            strList.Add('Chongqing');
            str := 'Chongqing';
            case strList.IndexOf(str) of
            0: ShowMessage('First');
            1: ShowMessage('Second');
            2: ShowMessage('Third');
            3: ShowMessage('Forth');
            else ShowMessage('Other');
            end;
            strList.Free;

可以看到,這是比較麻煩的方法了,不過你可得記住這個方法,因爲後面的討論
            將會講到,這是最通用的方法。
            另:當然,把字符串轉化爲整型後用於 case 不只這一種方法。另一種是通過把
            備選項全部轉化爲等長度後合併爲一個字符串,然後用 Pos 函數返回某字符串的
            位置。在此不再累述,請查閱《程序員》雜誌(具體哪一期不記得了:-()。

(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
法二:字符串轉爲字符型

這應該是最簡單的一種方法,不過侷限性比較大。如果你的備選項的第 N 個字
            符(N 應爲常數)都互不相同,那麼你賺到了。這樣,就可以通過取出這個字符,
            來唯一標識你的字符串:

str := 'Chongqing';
            case str[1] of // 第一個字符都不同,所以取出第一個進行比較
'B': ShowMessage('First');
            'T': ShowMessage('Second');
            'S': ShowMessage('Third');
            'C': ShowMessage('Forth');
            else ShowMessage('Other');
            end;

不過如果你的備選項沒有這樣的特性,那麼你就無緣使用這種方法了。

(**** 轉載敬請註明-本文出處:南山古桃(nsgtao)的百度空間:http://hi.baidu.com/nsgtao/ ****)
法三:字符串轉爲枚舉型

這種方法主要用到 RTTI 的特性。該方法的主要思路是,先把所有的備選項聲名
            爲一個枚舉類型的值,那麼我們只要把要找的字符串也轉換爲枚舉型,那麼就可以
            用 case 語句了。那麼通過什麼辦法把一個字符串轉化爲枚舉型呢?往下看:

// uses TypInfo; // 記得引用這個單元
// type TMyStrSel = (Beijing, Tianjing, Shanghai, Chongqing);
            // 注意,上面這個定義不能放在某個函數內部哦,那樣的話,它就沒有運行類信息了
// var strSel: TMyStrSel;

str := 'Chongqing';
            strSel := TMyStrSel(GetEnumValue(TypeInfo(TMyStrSel), str));
            case strSel of
            Beijing: ShowMessage('First');
            Tianjing: ShowMessage('Second');
            Shanghai: ShowMessage('Third');
            Chongqing: ShowMessage('Forth');
            else ShowMessage('Other');
            end;

稍做解釋:GetEnumValue 函數返回一個字符串對應的枚舉型的值在某枚舉類型
            中的位置(要知道枚舉類型是有順序的,要不怎麼叫順序類型呢:-)),然後通過
            一個強制類型轉換將這個值轉化爲枚舉型。於是就實現了把字符串轉化爲枚舉型的
            操作。

可以看到,在 case 語句這一段,我們的使用和理想中的使用方法幾乎是一樣的!
            畢竟枚舉類型可以做到見名知意嘛。的確比用前兩種方法看起來直觀得多。

當然,這並不是萬能的方法,如果你的備選項有一個不符合 Delphi 的變量名命
            名法則(如'AK-47'或中文等),則不能將其聲明爲一個枚舉型,於是就不能使用這
            個方法。如果是這樣你就只能使用前兩種方法了。極端的情況下,至少你還有第一
            種方法可以使用 :-) 但在不少的場合,這種方法還是適用的。


Case 語句中使用字符串
            作者:

function CaseString (const s: string;
                                  const x: array of string): Integer;
            var i: Integer;
            begin
            Result:= -1; // Default return parameter
            for i:= Low (x) to High (x) do begin
            if s = x[i] then begin Result:= i; Exit; end;
            end;
            end;

search:= 'delphi3000';
            case CaseString (search, ['delphi3000',
                                        'delphipages',
                                        'Torry's']) of
            0: s:= 'Excellent!';
            1: s:= 'Good source';
            2: s:= 'Not bad!';
            end;
            /////////////////////////////////

const MatchingStrings = '*First*Second*Third*';
            var sString: string;
            ...

// sString has the data you want to test
            case pos('*'+sString+'*',MatchingStrings) of
                1:     // This is the match for 'First'
                7:     // This is the match for 'Second'
                14:    // This is the match for 'Third'
                else // In this case there were no matches
                end;

unit Unit1;

interface

uses
              Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
              Dialogs, StdCtrls;

type
              TForm1 = class(TForm)
                 btn1: TButton;
                 grp1: TGroupBox;
                 rb1: TRadioButton;
                 rb2: TRadioButton;
                 procedure btn1Click(Sender: TObject);
              private
                 { Private declarations }
              public
                 { Public declarations }
              end;

type TASK=(blue,green,black,white,maroon);

var
              Form1: TForm1;

const
                Taskzhaowang:TASK=blue;
                Taskneizheng:TASK=green;

implementation

{$R *.dfm}

procedure asdf(t:task)  ;
            begin
              case t of
                  blue:
                     ShowMessage('ZhaoWang:'+inttostr(Ord(t)));
                  green:
                     ShowMessage('NeiZhneg:'+inttostr(Ord(t)));
              end;
            end;

procedure TForm1.btn1Click(Sender: TObject);
            begin
              if(rb1.Checked) then asdf(Taskzhaowang);
              if(rb2.Checked) then asdf(Taskneizheng);
            end;

end.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章