如何检查动态数组是否为空

10

我有一个过程声明如下:

procedure MyProc(List: Array of string);
我想知道如何检查 List 参数是否为空。
例如:
procedure MyProc(List: Array of string);
begin
  if List=[] then // here I want to check if the List array is empty
  //do something
  else 
  //do something else
end;

我该如何做到这一点?


4
你应该写成 MyProc(const List: array of string),因为在你的代码中,在调用 MyProc 过程之前,所有字符串都会被复制到一个临时数组中。而 if pointer(List)=nil then 是检查动态数组是否为空的最快方法。 - Arnaud Bouchez
1
指针(list)抛弃了类型安全并依赖于实现细节。 - David Heffernan
据我所知,如果没有const限定符,那么只有在您在MyProc中修改数组时,它才会被复制到一个新的(临时)数组中,而不是在调用之前(动态数组遵循COW策略,就像字符串一样)。 - Bozzy
@Bozzy 我确实没有说得很准确:并不是所有的字符串都被复制到临时数组中。但是字符串的引用计数会增加,然后减少,因此会有两个不必要的RTL调用。所以如果你使用const,就不会有这些AddRef/DecRef隐藏过程调用。 - Arnaud Bouchez
3个回答

25
你可以使用 Length 函数。
procedure MyProc(List: Array of string);
begin
  if Length(List)=0 then // is empty ?
  //do something
  else 
  // do something else
end;

12

空数组等于 nil

if List = nil then // it's empty

这也意味着SetLength(List, 0)List := nil是等效的命令。

空数组的最后一个索引小于第一个索引,对于你示例中的开放数组来说,这意味着具有负的最后一个索引:

if High(List) < 0 then // it's empty

这意味着,如果你想避免在空数组上运行循环,你不需要做任何特殊处理。只需按照正常的方式编写循环即可:

for i := Low(List) to High(List) do // won't run if List is empty

你确定 if List = nil then 吗?这行代码无法编译通过。 - RRUZ
1
如果指针(List)= nil,则是检查动态数组是否为空的最快方法(比length(List)= 0更快)。 - Arnaud Bouchez
2
@RRUZ:这是因为List = nil仅适用于动态数组(就像这个问题的标题中所示),而不适用于开放数组(就像这个问题的示例中所示)。发帖人混淆了动态数组和开放数组。 - The_Fox
我不喜欢使用Assigned(List)或任何其他变体来检查数组是否为空的想法。例如,比较一下TList类。MyTList = nilMyTList.Count = 0之间有着显著的不同含义。尽管不存在的东西不能有任何项 - 但是它不存在的事实可能是一个重大的错误。因此,我更愿意坚持使用Length(List),最好是for I:= Low(List) to High(List),因为它对于所有三种类型的数组都是相同的。(+1任何情况下都适用:“如果List为空,则不运行”) - Disillusioned

2

个人而言,我总是写

if Assigned(List) then

更适合于
if List<>nil then

因为我认为这样读起来更好,不仅适用于动态数组。
这回答了关于动态数组的问题,但你的例子是一个开放数组,所以这里有两个可能的问题。
对于开放数组,我会使用Length()high()来根据数组的大小做出决策。 我不会被Pointer(List)<>nilLength(List)<>nil更快的论点所诱惑。 这些选项之间的速度差异不会被注意到,因此应该使用最清晰和可读性最强的选项。

我同意。这比另一种方式更像Delphi。+1 - 0xC0000022L
1
我不喜欢使用Assigned(List)或任何其他类似的方法来检查数组是否为空。例如,比较一下TList类。MyTList = nilMyTList.Count = 0之间有着显著的不同含义。虽然不存在的东西不能有任何项 - 但是它不存在这个事实可能是一个重要的错误。因此,我更愿意坚持使用Length(List),最好是for I := Low(List) to High(List),因为它对于所有三种类型的数组都是相同的优势。 - Disillusioned
@Craig 在实践中,我认为人们不会轻易混淆动态数组和对象,但我理解你的观点。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接