我应该使用&#34; TList <string>&#34;而不是&#34;字符串数组&#34;总是?</字符串>

时间:2014-06-17 22:29:34

标签: delphi

我一直在迁移Delphi 7中开发的项目,并且每次以前的开发人员想要使用他们创建的集合时都会查看代码:

ArrayOfString : array of string;
ArrayOfInteger: array of integer;
ArrayOfStringArrays : array of ArrayOfString;

这种代码在很多地方都会重复,而且每次都会为它们中的每一个重复“SetLength”,我想知道是否将所有这Array of Something更改为TList<Something>现在我们在Delphi中XE4。

这样做有什么好处,资源,速度或类似的东西可以支持我做出这个决定?

PS:我来自JAVA和Delphi给我感到黑暗和充满恐惧

3 个答案:

答案 0 :(得分:10)

将动态数组视为低于TStringListTList<T>的低级构造。

动态数组通过指针提供对元素的直接访问。该语言隐藏了指针,但基本上所有的动态数组都是。但是你负责任何重新分配,如果你想插入或删除项目,那么你必须编写代码,并处理细节。

更高级别的集合类TStringListTList<T>构建在动态数组之上。这是内部如何存储内容。但是集合类为你包装了这个。作为方法提供了诸如插入和删除等更高级别的操作。实质上,这些集合类比原始动态数组提供了更多的便利。

为了说明,请考虑插入项目的行为。对于动态数组,您可以这样做:

  1. 调整阵列大小。
  2. 将插入点之后的项目从位置i移动到i + 1。
  3. 分配插入的项目。
  4. 如果您需要多次编写此代码,那么,您做错了。

    对于你写的高级集合:

    List.Insert(Index, Value);
    

    让课程处理细节。

    请注意,由于历史原因,并且因为字符串特别重要,开发人员倾向于使用定制的专用TStringList类而不是TList<string>。同样,专用类提供了TList<string>之外的功能,因为它专门用于字符串,并且可以提供定制到字符串的功能。同样,专用课程提供了便利。

    动态阵列派上用场的一个地方就是当你不想招致终身管理的样板时。因此,对于没有针对类的ARC的桌面编译器,您需要明确销毁TList<T>个实例。但动态阵列的生命周期由ARC管理。如果您一次性合成数组,然后不调整它们的大小,那么生命周期管理问题可以使数组更方便使用。

    根据经验,喜欢高级集合类。它们应该是您的默认选择。有时动态数组是正确的选择,但这往往适用于更专业的场景。

答案 1 :(得分:6)

首先,在较新版本的Delphi中,有TArray<T>类型可用于替换所有旧的array of whatever声明。使用它可以解决语言中的一些长期陷阱,从经典的Pascal遗留下来,并帮助你不要遇到混乱的错误。

话虽如此,TStringList不是字符串数组;它是一个容器对象,它包含一个字符串列表。它有几种专门的字符串列表处理方法,使它非常通用:它基本上可以用作字符串列表,一组字符串(通过.Sorted属性),一个字符串/对象映射(通过.Objects属性)和字符串/字符串映射(通过.Names.Values属性。)

如果您发现您在阵列上大量调用SetLength,特别是如果它类似于以下内容,您肯定应该将其转换为列表类:

for i := 0 to Count - 1 do
begin
   SetLength(myArray, length(myArray) + 1);
   myArray[high(myArray)] := values[i];
end;

使用通用TList<T>TStringList,这将成为:

for i := 0 to Count - 1 do
begin
   myList.Add(values[i]);
end;

这既易于阅读又具有更高的性能(尤其是具有较大的Count值),因为列表类能够在内部跟踪它们的大小并保持内存重新分配。所以列表类在大多数情况下都是双赢的。在某些情况下,您更喜欢动态数组,但它们很少见。

有一件事需要注意:如果您来自Java背景,请记住动态数组是编译器管理的类型,但列表类是需要在代码中释放的对象。

答案 2 :(得分:0)

除非您特别需要和String of String,否则我强烈建议使用TStringList。我个人根本不会使用TList。 TStringList提供了我所需要的一切,只有少数情况需要求助于一个字符串数组。

可以通过myStringList.Items [i]或者甚至只是myStringList [i]来访问TStringList,就像数组一样。

你不需要保持更改长度或保持计数,你只需要myStringList.Add(aString)和myStringList.Count(不要忘记循环的-1)。

它还具有所有列表操作所需的例程,用于添加,删除,重新排序,排序等。

它也可以作为参数传递,而不需要像数组类型那样的其他声明。

希望这有帮助。