2009-07-29 41 views
2

考慮以下德爾福帕斯卡代碼:DELPHI:如何在循環或大小寫之外使用「break」?

var 
    tc: TComponent 
begin 
{ do something to get tc } 
repeat 
    if(tc is TDBEdit)then begin 
    if(check_something_about_edit(tc))then break; 
    do_something_else_edit(tc); 
    break; 
    end else if(tc is TBMemo) then begin 
    if(check_something_about_memo(tc))then break; 
    do_something_else_memo(tc); 
    break; 
    end; 
    raise exception.create('invalid component type'); 
until(true); {single iteration look required to use break } 

我知道可能有一些多態性的東西,我可以做TComponent,但是這不是我的問題。我想知道是否有辦法擺脫單迭代repeat-until語句。沒有它,我不能在處理塊的任何地方使用break語句,我需要在任何時候停止處理。

+1

事實上,你可以做的事情可能是「多態的東西」這兩種組件類型都是從'TCustomEdit'下降的。改變'tc'的聲明。 – 2009-07-29 16:19:50

+2

+1。雖然您發佈的代碼非常殘酷,但您如何改進它卻是正確的。每當你有一個永遠不會執行超過一次的循環時,你就會犯錯。 – 2009-07-29 16:24:05

回答

4

將它裝入一個函數並使用exit跳回。如果有更多的代碼要遵循重複聲明,請使用本地函數/過程,如:

procedure ... 
    procedure testsomething(tc: TComponent); 
    begin 
    if(tc is TDBEdit)then begin 
     if(check_something_about_edit(tc))then exit; 
     do_something_else_edit(tc); 
     exit; 
    end else if(tc is TBMemo) then begin 
     if(check_something_about_memo(tc))then exit; 
     do_something_else_memo(tc); 
     exit; 
    end; 
    raise exception.create('invalid component type'); 
    end; 

var 
    tc: TComponent; 
begin 
{ do something to get tc } 
    try 
    TestSomething(tc); 
    { do something more } 
    except 
    ... 
    end; 
end; 
+0

雖然if-else解決方案在這種特定情況下更爲正確,但此解決方案更適用於真實情況。它需要移動一堆代碼,但沒關係。我更喜歡讓事情正確。 – 2009-07-29 21:11:25

4

您實際上在做什麼是使用break作爲goto。拉爾夫建議使用函數作爲範圍是一個好主意。但否則,你可能會誠實地使用'goto finished'。丟失重複將使其更具可讀性。

+0

嗯,一個goto比break更實際/更少/更邪惡的情況。奇怪的日子...... – 2009-07-29 21:05:23

+0

那麼,你提出了一個非常邪惡的使用休息。無論如何,break/continue都是結構化的goto。 – 2009-07-29 21:24:59

14

還有一種簡單的方法去:

if(tc is TDBEdit)then begin 
    if not (check_something_about_edit(tc)) then 
    do_something_else_edit(tc); 
end else if(tc is TBMemo) then begin 
    if not (check_something_about_memo(tc)) then 
    do_something_else_memo(tc); 
end else 
    raise exception.create('invalid component type'); 
end; 
+0

我認爲這是比你發佈的第一個更好的選擇。 – 2009-07-29 16:21:30

+0

我也是如此,但花了一段時間才能通過代碼;) – 2009-07-29 16:26:52

+0

我離開另一個,也許它可以在類似的設置有用。 – 2009-07-29 16:27:25

1

你爲什麼想用突破,而不是退出? Delphi中的打破與大括號語言中的「打破」不同。

var 
    tc: TComponent 
begin 
    { do something to get tc } 
    if (tc is TDBEdit) then 
    begin 
    if not (check_something_about_edit(tc)) then 
     do_something_else_edit(tc); 
    Exit; 
    end; 
    if (tc is TBMemo) then 
    begin 
    if not (check_something_about_memo(tc)) then 
     do_something_else_memo(tc); 
    Exit; 
    end; 
    raise exception.create('invalid component type'); 
end; 

關於佈局的一點。如果你沒有儘量減少空白,那麼 可能需要「再花一個小時來確保我所有的if-else都排好了」,正如你在前面的評論中所說的那樣。

如果你之後有想要執行的代碼,可以使用Ralph對本地過程的建議,或者在try..finally中包裝 - finally中的代碼仍將被執行。