将 For 循环转换为不使用变量
Convert For loop to not use variables
我在我的应用程序中经常使用 Virtual Treeview。为了构建节点,我使用这个过程,当我知道节点将有子节点时:
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;
当我 运行 Peganza 的 Pascal 专家(Pascal 分析器集成到 IDE 中)时,它给我消息说 'j' 变量没有在 For 循环中使用:
[Pascal Expert] WARN42: Standards.pas(428): j For-loop variables not used in loop
我理解该消息,事实证明它在我使用 'i' 而不是 'j' 等的其他情况下很有用(来自复制粘贴的代码),但在这种情况下没有用。
由于我在许多虚拟树视图中使用相同的代码,因此我多次出现此警告。
关于如何更改此 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;
我认为没有任何方法可以更简洁地编写该代码。退一步讲,for 循环有多种用途,但可能主要有以下两种:
- 对集合的每个成员执行一个操作。
- 执行一个动作N次。
这显然是一种简化,但如果您查看代码库中的 for 循环,您会发现它们总是属于一类或另一类。
现在,正在考虑的代码属于第二类。它是这样的形式:
for I := 1 to N do
Foo();
你还能怎么写这个?您可以使用另一种形式的循环,其中有 while
和 repeat
。正如您在 while
的情况下所观察到的,两者都不会产生更清晰的代码。另一种选择是使用递归实现来实现迭代。那不会更简单。
得出的结论是您的静态分析工具拒绝了一种常见且有效的迭代形式。问题不在于你的代码薄弱,而在于静态分析误诊了一个不存在的问题。
解决方案:抑制或忽略这些特定的静态分析警告。
我在我的应用程序中经常使用 Virtual Treeview。为了构建节点,我使用这个过程,当我知道节点将有子节点时:
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;
当我 运行 Peganza 的 Pascal 专家(Pascal 分析器集成到 IDE 中)时,它给我消息说 'j' 变量没有在 For 循环中使用:
[Pascal Expert] WARN42: Standards.pas(428): j For-loop variables not used in loop
我理解该消息,事实证明它在我使用 'i' 而不是 'j' 等的其他情况下很有用(来自复制粘贴的代码),但在这种情况下没有用。 由于我在许多虚拟树视图中使用相同的代码,因此我多次出现此警告。
关于如何更改此 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;
我认为没有任何方法可以更简洁地编写该代码。退一步讲,for 循环有多种用途,但可能主要有以下两种:
- 对集合的每个成员执行一个操作。
- 执行一个动作N次。
这显然是一种简化,但如果您查看代码库中的 for 循环,您会发现它们总是属于一类或另一类。
现在,正在考虑的代码属于第二类。它是这样的形式:
for I := 1 to N do
Foo();
你还能怎么写这个?您可以使用另一种形式的循环,其中有 while
和 repeat
。正如您在 while
的情况下所观察到的,两者都不会产生更清晰的代码。另一种选择是使用递归实现来实现迭代。那不会更简单。
得出的结论是您的静态分析工具拒绝了一种常见且有效的迭代形式。问题不在于你的代码薄弱,而在于静态分析误诊了一个不存在的问题。
解决方案:抑制或忽略这些特定的静态分析警告。