Delphi 将For循环转换为不使用变量

Delphi 将For循环转换为不使用变量,delphi,for-loop,delphi-xe7,Delphi,For Loop,Delphi Xe7,我在我的应用程序中经常使用虚拟树视图。为了构建节点,当我知道节点将有子节点时,我使用以下步骤: VTV.BeginUpdate; VTV.Clear; for i := 0 to Length(vArray) - 1 do begin // Add a node to the root of the Tree if i = 0 then begin Node := VTV.AddChild(nil); Data := VTV.GetN

我在我的应用程序中经常使用虚拟树视图。为了构建节点,当我知道节点将有子节点时,我使用以下步骤:

 VTV.BeginUpdate;
  VTV.Clear;
  for i := 0 to Length(vArray) - 1 do
  begin
    // Add a node to the root of the Tree
    if i = 0 then
    begin
      Node := VTV.AddChild(nil);
      Data := VTV.GetNodeData(Node);
    end
    else
    begin
      if vArray[i].Level = 0 then Node := VTV.AddChild(nil)
      else if vArray[i].Level > vArray[i - 1].Level then Node := VTV.AddChild(Node)
      else if vArray[i].Level < vArray[i - 1].Level then
      begin
        Node := Node.Parent;
        for j := 1 to (vArray[i - 1].Level - vArray[i].Level) do // line#: 428 warning: j not used!
          Node := Node.Parent;
        Node := VTV.AddChild(Node);
      end
      else
      begin
        Node := Node.Parent;
        Node := VTV.AddChild(Node);
      end;
      Data := VTV.GetNodeData(Node);
    end;
    // Create link to your data record into node
    Data.IndexInMyData := i;
    vArray[Data.IndexInMyData].NodePointer := Node;
  end;
  VTV.EndUpdate;
我理解这条消息,在我使用“I”而不是“j”之类的其他情况下(从复制粘贴的代码中),它被证明是有用的,但在这种情况下不是。 由于我在许多虚拟TreeView中使用相同的代码,因此多次出现此警告

有没有建议如何更改此For循环,使我不再收到此消息?

for j := 1 to (vArray[i - 1].Level - vArray[i].Level) do
          Node := Node.Parent;
我更希望长度与当前相同或更短,我不希望有这样的东西-这是太多的代码:

j:=1;
while j <= (vArray[i - 1].Level - vArray[i].Level) do
begin
  Node := Node.Parent;
  Inc(j);
end;
j:=1;

然而,我认为没有任何方法可以以更干净的方式编写代码。退一步说,for循环有多种用途,但可能有以下两种主要用途:

  • 对集合的每个成员执行操作
  • 执行一个动作N次
这显然是一种简化,但如果您查看代码库中的for循环,您会发现它们总是属于一个类别或另一个类别

现在,考虑中的代码属于第二类。其形式如下:

for I := 1 to N do
  Foo();
你还能怎么写这个?您可以使用另一种形式的循环,其中有
while
repeat
。正如您在
while
中所观察到的,这两种方法都不会产生更干净的代码。另一种选择是使用递归实现来实现迭代。这并不简单

由此得出的结论是,您的静态分析工具拒绝了一种常见且有效的迭代形式。问题不在于您的代码很弱,而在于静态分析错误地诊断了一个不存在的问题


解决方案:抑制或忽略这些特定的静态分析警告

我认为没有任何方法可以以更简洁的方式编写代码。退一步说,for循环有多种用途,但可能有以下两种主要用途:

  • 对集合的每个成员执行操作
  • 执行一个动作N次
这显然是一种简化,但如果您查看代码库中的for循环,您会发现它们总是属于一个类别或另一个类别

现在,考虑中的代码属于第二类。其形式如下:

for I := 1 to N do
  Foo();
你还能怎么写这个?您可以使用另一种形式的循环,其中有
while
repeat
。正如您在
while
中所观察到的,这两种方法都不会产生更干净的代码。另一种选择是使用递归实现来实现迭代。这并不简单

由此得出的结论是,您的静态分析工具拒绝了一种常见且有效的迭代形式。问题不在于您的代码很弱,而在于静态分析错误地诊断了一个不存在的问题


解决方案:抑制或忽略这些特定的静态分析警告

在for循环中使用
j
是可以的。没有必要对警告信息反应过度。我不会因为第三方工具发出警告而感到太不安。循环变量的使用方式很好。在for循环中使用
j
是可以的。没有必要对警告信息反应过度。我不会因为第三方工具发出警告而感到太不安。循环变量的使用方式很好。谢谢,我同意它应该是无关的。问题是我有数千个for循环,主要是我复制了它们之间的代码,有些使用I,有些使用j,所以当复制时,我可能会忽略这个差异,而不是改变它。其中一个问题每年至少出现一次,因此我依赖于此警告。因此,以不同的方式重新编写for循环,但不要期望它提供更干净的代码。代码将更难理解。如果你认为这将导致更少的错误,我认为你错了。混淆从来都不是有益的。我刚刚就如何使构建节点的代码可重用提出了新的问题。若我可以创建AddNode通用过程,在我的所有代码中都可以重用,那个么我就可以很容易地更改“j”的使用方式,因为它只在一个地方。在这种情况下,一些额外的行,比如使用
While
,不是问题。我希望你们能抽出一些时间来看看新的问题。你们是对的,这已经是干净的代码了。这里没什么可做的。谢谢你,我同意这应该是无关紧要的。问题是我有数千个for循环,主要是我复制了它们之间的代码,有些使用I,有些使用j,所以当复制时,我可能会忽略这个差异,而不是改变它。其中一个问题每年至少出现一次,因此我依赖于此警告。因此,以不同的方式重新编写for循环,但不要期望它提供更干净的代码。代码将更难理解。如果你认为这将导致更少的错误,我认为你错了。混淆从来都不是有益的。我刚刚就如何使构建节点的代码可重用提出了新的问题。若我可以创建AddNode通用过程,在我的所有代码中都可以重用,那个么我就可以很容易地更改“j”的使用方式,因为它只在一个地方。在这种情况下,一些额外的行,比如使用
While
,不是问题。我希望你们能抽出一些时间来看看新的问题。你们是对的,这已经是干净的代码了。这里没什么可做的。