Delphi 枚举器中的规范 MoveNext 是这样编写的:
function TListEnumerator.MoveNext: Boolean;
begin
Result := FIndex < FList.Count - 1;
if Result then
Inc(FIndex);
end;
这是整个 RTL、VCL 等使用的形式。这种形式似乎在 3 rd方代码中也很普遍。
我认为它可以更简单地写成这样:
function TListEnumerator.MoveNext: Boolean;
begin
Inc(FIndex);
Result := FIndex < FList.Count;
end;
为什么不能使用更简单的形式有什么好的理由吗?
我的推理如下。一旦MoveNext返回False,该Current属性将不再被访问。不在列表末尾没关系,FIndex因为它再也不会使用了。for in 循环实际上是这样实现的:
while Enumerator.MoveNext do
Enumerator.Current.DoSomething;
事实上FIndex,越界对我来说实际上更有意义。这意味着如果有人使用手写的枚举器代码,那么如果在返回Current后访问,他们将得到范围检查错误。MoveNextFalse
更重要的FIndex是-1,在第一次调用MoveNext. 这是左边列表中的一个。在最后一次调用 之后MoveNext,返回的那个False不是合适的,FIndex就是Count右边列表中的那个。