德尔福:在这种情况下,Goto不被视为有害吗?

时间:2010-10-17 00:48:30

标签: delphi goto

好的,所以你有一个TObjectList实例。您想循环遍历其中的项目并从列表中删除一些对象。你不能这样做:

for I := 0 to ObjectList.Count - 1 do
  if TMyClass(ObjectList[I]).ShouldRemove then
    ObjectList.Delete(I);

...因为一旦删除第一个对象,索引计数器就会出错,循环将不再起作用。

所以这是我的解决方案:

Again:
  for I := 0 to ObjectList.Count - 1 do
    if TMyClass(ObjectList[I]).ShouldRemove then
    begin
      ObjectList.Delete(I);
      goto Again;
    end;

这是迄今为止我发现的最佳解决方案。如果有人有一个更整洁的解决方案,我很乐意看到它。

3 个答案:

答案 0 :(得分:30)

请改为尝试:

 for I := ObjectList.Count - 1 downto 0 do
   if TMyClass(ObjectList[I]).ShouldRemove then
     ObjectList.Delete(I);

这看起来像是一个特别糟糕的使用goto,跳出了那样的for循环。我认为它有效(因为你正在使用它),但它会给我一些意志。

答案 1 :(得分:7)

您也可以使用

  I := 0;
  while I < ObjectList.Count do begin
    if TMyClass(ObjectList[I]).ShouldRemove then ObjectList.Delete(I)
    else Inc(I);
  end;

答案 2 :(得分:0)

我见过的唯一有效使用Goto是Delphi帮助中提供的。

for I := 0 to something do
begin
  for J := 0 to something do
  begin
    For K := 0 to something do
    begin
      if SomeCondition then
        Goto NestedBreak
    end;
  end;
end;
NestedBreak:

虽然可以通过在本地函数中移动循环并使用EXIT来避免Goto,例如。如果不接受子功能,您仍然可以这样做:

for I := 0 to something do
begin
  for J := 0 to something do
  begin
    For K := 0 to something do
    begin
      if SomeCondition then
      begin
        GottaBreak := True
        Break;
      end; 
    end;
    if GottaBreak then Break;
  end;
  if GottaBreak then Break;
end;

这只是不太理想。

我还没有看到其他情况,其中Goto是最佳解决方案。(或任何好处)。

转到本身并不错。这是一个流程控制命令,就像EXIT,BREAK或CONTINUE一样。除了那些其他仅限于特定情况并由编译器正确管理。 (话虽如此,我与之谈过的一些程序员认为那些与Goto一样有害,我不同意的观点)转到不受限制,你可以用它做的事情会产生非常负面的影响。无论如何,我认为我已经超出了问题的范围。 ^ _ ^