我有一段这样的代码:
for I := 0 to Self.EventQueue.Count do
Dispose(Self.EventQueue[I]);
当Count为0时,它会发出错误,因为它会尝试Dispose
一个不存在的元素。当我将其更改为
for I := 0 to Self.EventQueue.Count-1 do
Dispose(Self.EventQueue[I]);
一切正常。是否有任何优雅的方式来解决这个问题,还是这种常见做法?
答案 0 :(得分:0)
OMG。那是因为在循环中从0到Self.EventQueue.Count,你遍历Self.EventQueue.Count + 1项。
答案 1 :(得分:0)
这是绝对正常的行为,并且在Delphi / FreePascal中的每个列表和容器类的帮助中都有记录。原因很清楚 - 如果列表中有三个项目,并且第一个项目位于索引0
,那么您有0, 1, 2
项,但Count
为3
,对吗?
for i := 0 to StringList.Count - 1 do // TStringList
for i := 0 to List.Count - 1 do // TList
for i := 0 to StringGrid1.ColCount do // TStringGrid
另一种选择并不那么明确(对我来说输入更糟糕):
for i := 0 to Pred(StringList.Count) do
动态数组也从索引0
开始。
var
IntArray: array of Integer;
i: Integer;
begin
SetLength(IntArray, 10);
for i := Low(IntArray) to High(IntArray) do // loop is 0..9
//
end;
FPC / Delphi中唯一不是0
的东西是从1
开始的字符串类型和非动态数组(在代码中声明为固定大小的数组) ,几乎可以从你想要的任何索引开始。例如,这是完全合法的:
var
IntArray: array[-10..10] of Integer;
i: Integer;
begin
for i := Low(IntArray) to High(IntArray) do // loop is -10..10
//
end;
除此之外,无论何时你在循环中做任何会减少列表中项目数量的事情,你都应该向后迭代:
for i := List.Count - 1 downto 0 do
否则,您将迭代超出列表的末尾,因为Count
仅在循环开始时进行评估。
答案 2 :(得分:0)
我更喜欢使用
for I := 1 to Self.EventQueue.Count do
Dispose(Self.EventQueue[I-1]);
很明显,如果计数为零并且指数的修正发生在重要的地方,则没有任何反应