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

Dav*_*vid 4 delphi goto

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

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

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

所以这是我的解决方案:

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

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

Lar*_*tig 30

试试这个:

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

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

  • 好吧,我明白为什么它现在有效.因为你倒计时,列表缩小并不重要.后续索引都是有效的.我现在要改变我的愚蠢代码. (6认同)
  • 请记住,Larry的解决方案是针对此特定问题(基于索引的删除)的众所周知的标准解决方案,适用于除"Delphi"和/或"TObjectList"之外的更多情况.这是一个重要的工具. (3认同)
  • 基本上,它表明此问题仍然不需要使用Goto.:-)在我20多年的Pascal编程经验中,我了解到如果你考虑使用goto,你就会错过一个更好的解决方案.我从来没有,需要使用这个愚蠢的命令. (3认同)

klu*_*udg 7

你也可以使用

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