4

好的,所以你有一个 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;

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

4

3 回答 3

30

试试这个:

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

这看起来像是对 goto 的特别糟糕的使用,像这样跳出 for 循环。我认为它有效(因为您正在使用它),但它会给我带来威力。

于 2010-10-17T00:51:41.443 回答
7

你也可以使用

  I := 0;
  while I < ObjectList.Count do begin
    if TMyClass(ObjectList[I]).ShouldRemove then ObjectList.Delete(I)
    else Inc(I);
  end;
于 2010-10-17T01:24:37.887 回答
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 是最好的解决方案的其他情况。(或任何好的)。

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

于 2010-10-17T01:06:34.103 回答