DELPHI: como usar fora “break” de loop ou caso?
Pergunta
considere o seguinte código pascal delphi:
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 }
Eu sei que há provavelmente algumas coisas polimórfico que eu poderia fazer com TComponent, mas isso não é a minha pergunta. Eu estou querendo saber se há uma maneira de se livrar da única iteração repeat-until comunicado. Sem ele, eu não posso usar a qualquer instrução break no bloco de processamento, e eu preciso que pare de processar a qualquer momento.
Solução
embalá-lo em uma função e uso de saída para saltar para trás. se houver mais de código a seguir a instrução repeat, usar uma função / procedimento local, algo como:
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;
Outras dicas
Há uma outra maneira fácil de ir:
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;
O que você está realmente fazendo é usando pausa como um goto. A sugestão de Ralph usar uma função como um escopo é uma boa. Mas caso contrário, você pode muito bem ser honesto e usar um 'Goto acabado'. Perder a repetição fará com que seja realmente mais legível.
Por que você quer usar break em vez de Sair? Break in Delphi não é o mesmo que "break" nas línguas chaveta.
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;
Um ponto sobre o layout. Se você não tentar reduzir espaços em branco tanto que talvez não tomar "mais uma hora para se certificar de toda a minha if-else de alinhados corretamente", como você disse em um comentário anterior.
Se você tem o código que você deseja executar após isso, use a sugestão de Ralph de um procedimento local, ou envoltório em um try..finally -. O código na finalmente ainda será executado