Arrays 在Delphi中定义记录-(记录为类型vs记录为变量)-区别、利弊。。?

Arrays 在Delphi中定义记录-(记录为类型vs记录为变量)-区别、利弊。。?,arrays,delphi,record,Arrays,Delphi,Record,我在Delphi中对记录进行了一些研究,在大多数情况下,我看到它们被用作类型,然后声明了它的一个新变量,例如: type TMyRecord = record data1: sometype; data2: sometype; end; var OnesRecord: TMyRecord; var OnesRecord: record data1: sometype; data2: sometype; end; 对于阵列,它还用作: ty

我在Delphi中对记录进行了一些研究,在大多数情况下,我看到它们被用作类型,然后声明了它的一个新变量,例如:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: TMyRecord;
var
  OnesRecord: record
    data1: sometype;
    data2: sometype;
  end;
对于阵列,它还用作:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: array of TMyRecord;
我的问题如下:

为什么不应该对阵列使用第一种方法,具体如下:

type
  TMyRecord = array of record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: TMyRecord;
此外,如果使用直接定义为变量的记录,例如:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: TMyRecord;
var
  OnesRecord: record
    data1: sometype;
    data2: sometype;
  end;

?

最后一件事;如果将第二种方法和第三种方法合并,并具有数组类型和该类型的数组变量,这与具有数组类型的数组有什么不同吗

那么,这是:

type
  TMyRecord = array of record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: array of TMyRecord;
与此不同的是:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: array of array of TMyRecord;

使用
类型
声明,您可以轻松地在多个其他类型或变量中使用它,并将该类型的变量或常量传递给过程和函数

Type 
  TCatRecord = Record
    Name  : string;
    Color : string;
  End;
  TCatArray = Array of TCatRecord;
Var
  MyCat : TCatRecord;
  NeighbourhoodCats : TCatArray;
...
Procedure SpayACat(aCat: TCatRecord);
Function PickCutestCat(SomeCats: TCatArray): TCatRecord;
...
MyCat := PickCutestCat(NeighbourhoodCats); 

做你正在做的事情没有错,就像没有什么可以阻止你重载Add()操作符来做乘法一样

你的问题完全是理论性的,所以很难以这样或那样的方式说出来。是的,这些结构是“合法的”。那又怎样

这就像在你发现自己可以用手走路后,问自己是用手走路还是用脚走路

所有情况下的问题都是一样的。。。你为什么要这么做

与其询问那些“合法”但没有人使用的编码方法,不如试着展示一个例子,说明这样的使用将证明是一种优势

从理论上讲,您正试图将两种不同的数据聚合机制混搭在一起

数组是收集相同类型项的一种方法。记录和分类是收集不同类型相关项目的一种方式。它们都是不同种类的容器,但它们有不同的特性

通常将数组声明为“array of”而不是“array of record…end”

按照惯例,您将记录定义为一个类型,以便可以“重用”该类型

显然,您在这方面没有太多经验,因为您无法在非常狭窄的环境之外实际使用这些构造

假设您想定义类似“整数数组”的东西;您可以将其定义为特定类型:

type
 TIntArray = array of integer;
你为什么要这样做?因为有时您会发现,将两个不同的事物同时声明为“整数数组”会使它们不兼容类型,这是违反直觉的

但是如果它们都声明为TIntArray,编译器会接受它

我不知道这是否是正确的术语,但就编译器而言,“myvar:”和“myvar:”之间存在差异。在本例中,将是“TIntArray”,并将是“整数数组”

这两种类型在所有情况下都不兼容。此外,

procedure myproc( AVar : array of integer )
将不接受myproc(myvar2),因为myvar2不是“整数数组”类型。真正地它属于数组类型。看到区别了吗

现在,用任何类型的“记录…结束”,甚至是“记录数组…结束”之类的东西替换该声明,您就会开始看到您所要求的限制。是的,编译器很好地消化了它。它只是不允许您将任何内容作为与该类型匹配的参数传入!即使他们“看起来”一模一样,信不信由你

因此,为了回答您自己的问题,我要求您构造一个非平凡的示例,在这个示例中,您提出的内容实际上是有意义的,并且编译器接受它们。因为虽然编译器可能会接受您在上面创建的独立示例,但它们在实践中不太可能工作得很好(如果有的话)


但如果你大胆地问了一个有见地的问题,你会得到“A”

这是一个相当简单的问题。这样写的时候

type
  TPoints = array of record
    X, Y: Double;
  end;
无法声明在数组的单个元素上操作的变量或参数。如果您不需要对单个项目进行操作,则上述声明可能是合理的

你问题的其他方面在逻辑上都是一样的。无论是数组数组、包含记录的记录、匿名记录还是作为变量类型的数组。问题和设计考虑事项完全相同


这个问题可能有点主观。根据我的经验,如上图所示,使用内联或匿名类型通常是一个错误的选择。通常,在未来开发的某个时候,很明显需要命名匿名类型

所以我自己,我从不使用由匿名类型组成的复合类型。通过这种方式,我总是能够重构代码,使用对单个元素进行操作的小方法。从来没有一个错误的约束将我推向在无法分解的复合类型上操作的大型方法

因此,我将上述类型声明为:

type
  TPoint = record
    X, Y: Double;
  end;
  TPoints = array of TPoint;

尽管在现代Delphi中,出于类型兼容性的原因,省略
TPoints
而使用
TArray
要好得多

为了补充choosen的答案,这里我们为单位中的全局变量提供了一个文档不太完善的功能:

声明具有初始化值的记录变量数组

type
  TPatch = Packed Record
    Pos: NativeUInt;
    Old: Byte;
    Sup: Byte;
  End;

var
  OpCodes: Array [1..5] of TPatch = (
    (Pos: $044773CF; Old: $7D; Sup: $EB),
    (Pos: $04477400; Old: $0D; Sup: $0B),
    (Pos: $0447D370; Old: $E3; Sup: $E9),
    (Pos: $0447D371; Old: $01; Sup: $99),
    (Pos: $0447D372; Old: $13; Sup: $00),
  );

现在您可以使用

我真的不明白为什么这值得向下投票,除非已经问过我没有注意到的地方……除了RTTI生成(或缺少RTTI生成),声明显式记录/数组类型的变量与声明带有内联记录字段的变量之间没有区别。内存布局和编译器管理的逻辑在这两种方式中都是相同的。那么,基本上上面所有的示例(除了数组部分)都是这样做的吗?使用特定模型有什么好处吗?@JustMarc:是的,他们都在做同样的事情。这只是个人喜好的一个方面,编译器不太在乎这种或那种方式。虽然如果您要在代码中传递记录,它会产生更多的错误