2014-04-29 30 views
13

我已经宣布了不少变量,是否安全,与在tarray代替XXX的阵列<XXX>

var 
    Something: array of XXX; 
begin 
    SetLength(Something, 10); 
    try 
    ... 
    finally 
    SetLength(Something, 0); 
    end; 
end; 

多大程度上是安全,让他们代替:

var 
    Something: TArray<XXX>; 
begin 
    SetLength(Something, 10); 
    try 
    ... 
    finally 
    SetLength(Something, 0); 
    end; 
end; 
+4

请注意:您不需要使用'try' /'finally'来释放动态数组类型的内存。它们是refcounted类型的,一旦'Something'超出范围,内存就会自动释放,除非它们仍然被另一个变量引用。无论哪种方式,它的行为与你的'SetLength'长度相同。 – hvd

回答

12

正如已经回答的那样,TArray<XXX>与定义为array of XXX的任何其他自定义类型完全相同。实际上,TArray<XXX>定义为array of XXX的自定义类型。

也就是说,定义为array of XXX的定制类型是而不是在过程或函数参数的上下文中相当于array of XXX。在procedure Foo(x: array of Integer),x是一个open array parameter,它可以接受任何类型的整数数组。相比之下,procedure Foo(x: TArray<Integer>)仅需要实际的TArray<Integer>类型。尝试传递固定大小的数组时,您可以看到差异,但也可以在尝试传递TDynIntegerArray(另一种类型,也定义为array of Integer)时看到差异。

因此,对于变量,当然,如果您有array of XXX,请将其更改为TArray<XXX>。只要确保你不做全球搜索和替换。

+0

+1用于区分变量和方法参数。但是,即使对于方法参数,除非您知道并分析代码,否则您无法为其中一方决定。虽然您可以将'TArray '传递给'XXX'数组,但不能将'XXX'数组传递给'TArray '。因此,在某些情况下,您可能会提出“TArray ”的参数,而在其他情况下,您可能希望将其保留为“XXX的数组”。 –

+0

我不同意第一段。这些类型不相同。它们是不同的类型,不兼容分配。 –

+0

@DavidHeffernan在第一段中,我选择的单词只有一个小问题。第二段有一个更大的错误。编辑我的答案来解决这个问题。 – hvd

5

这是完全安全去做这个。编译器将产生相同的输出。

我个人会在所有其他条件相同的情况下推荐这样做。通用数组TArray<T>的使用为您提供了更多的灵活性和更好的类型兼容性。

当然,这些好处只能用更实际的代码才能看到,可以完成一些工作。使用通用容器时,您通常会看到好处。但是,当您尝试使用多个不同的库构建代码时,您也可能会看到好处。

通用数组的使用允许简单的类型兼容性。通用阵列之前,你会定义一个数组类型是这样的:

TIntArray = array of Integer; 

如果两个库这样做,那么你有不兼容的类型。如果库同意使用通用数组,那么将会有兼容性。

为了更清楚地看到这一点,考虑这个片段:

type 
    TIntArray1 = array of Integer; 
    TIntArray2 = array of Integer; 
.... 
var 
    arr1: TIntArray1; 
    arr2: TIntArray2; 
.... 
arr1 := arr2; 

这种分配是无效的,失败与类型不匹配的编译器错误。这在Pascal语言中完全可以预料。毕竟它是强类型的,而且它们是不同的类型。即使它们的实施完全相同。

在另一方面:

var 
    arr1: TArray<Integer>; 
    arr2: TArray<Integer>; 
.... 
arr1 := arr2; 

是有效的,并编译。所述documentation for generic type compatibility说:

两个实例化的泛型被认为是兼容分配如果基类型是相同的(或者是别名为通用类型)和类型的参数是相同的。

+1

编译器将产生相同的输出...除非你关心RTTI,在这种情况下,不幸的是,'TArray '可能会失败。 (除非这个问题已经在新版本中修复?) –

+2

@MasonWheeler,确切地说! F.i. Datasnap使用的JSON封送处理可以完美地与声明为“数组T”的字段类型一起工作,但对于“TArray ”失败。因此,如此常见的答案是:这取决于。 –

+0

当然这已被修复。 'TArray '是根本。 –

相关问题