以下代码有效,但它不像for..in
循环那样干净/通用。
fInports: TArray<TMyClass>
for i:= low(fInPorts) to high(fInPorts) do begin
Port:= fInPorts[i];
Port.Left:= ARect.Left;
Port.Top:= ARect.Top + (Height div (NrInPorts+1)) * (i+1);
end; {for i}
for..in
循环更清晰,但不允许我查看正在访问的项目。
for Port in fInPorts do begin
Port.Left:= ARect.Left;
Port.Top:= ARect.Top + (Height div (NrInPorts+1)) * index;
//how do I get the index? -------------------------^^^^^^^
end; {for}
如何知道for..in
循环当前正在处理数组中的哪个项?
答案 0 :(得分:6)
for in
循环的重点是索引不应该相关。这是枚举器的决定,它将返回元素的顺序。枚举器可以更改元素返回的内部顺序,使用它的代码仍然可以工作。控件可以按类型,名称等进行排序。显然,在数组的情况下,编译器魔术按顺序返回数组的元素,但与其他枚举器不一定是这样。
如果你想要定位的索引,那么正如Jerry所说,你必须创建一个索引并在你的代码中使用它。如果它是TList
你可以作弊并使用IndexOf
,但从性能的角度来看,这会产生相反的效果。
就个人而言,我倾向于只谨慎地使用for in
循环,但这只是因为我老了。我太过控制狂了。
答案 1 :(得分:4)
使用for in循环时无法获取索引。几乎整个循环的重点是它们提供项目而不是索引。但是,您的代码根本不需要索引。
LLeft := ARect.Left;
LTop := ARect.Top;
for Port in fInPorts do begin
Port.Left:= LLeft;
Port.Top:= LTop + Height div (NrInPorts+1);
LTop := Port.Top;
end;
确实,调查员有权按任何顺序提供物品。但是,假设数组和列表的枚举器按特定顺序提供项目是非常合理的。这是按指数增加的顺序。
答案 2 :(得分:-1)
恕我直言,您应该更改TMyClass
课程以包含Index
属性。
怎么做?
在TMyClass单元中创建一个全局变量,并在Create()
构造函数上递增它,然后将新值赋给新对象的Index属性。
请勿忘记使用只读的已发布网址,其中包含FIndex
以避免错误修改。
在:
Port.Top:= ARect.Top + (Height div (NrInPorts+1)) * index;
后:
Port.Top:= ARect.Top + (Height div (NrInPorts+1)) * Port.Index;
完成! ; - )