考虑以下delphi pascal代码:
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语句,我需要随时停止处理。
答案 0 :(得分: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;
答案 1 :(得分:5)
将其打包到一个函数中并使用exit跳回。如果有更多代码要遵循repeat语句,请使用本地函数/过程,例如:
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;
答案 2 :(得分:4)
你实际上在做的是使用break作为goto。拉尔夫建议将函数用作范围是一个很好的建议。但除此之外你也可以诚实并使用'goto finished'。丢失重复将使其更具可读性。
答案 3 :(得分:1)
为什么要使用break而不是Exit? Delphi中的Break与大括号语言中的“break”不同。
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中的代码仍将被执行。