gpt4 book ai didi

arrays - Delphi - 指向 TRecord 的常量数组?

转载 作者:行者123 更新时间:2023-12-01 23:27:36 25 4
gpt4 key购买 nike

如何让一个变量指向一个记录数组?

注意:我希望将预定义的 TRecord 数组作为常量...但是在代码中,我需要变量“W”来记录要使用的记录数组。

请注意,我不希望使用 TRecord 的构造函数在代码中(动态地)创建 TRecord 数组,但希望拥有静态数组(因为数据不会更改)。

如何获取变量 'W' 以“记录”哪个 TRecord 数组?

请看下面的代码 - 更容易理解我的意思。

procedure TForm1.Button1Click(Sender: TObject);
type
TTestRec = record
X: string;
Y: Integer;
end;
TMyArr = TArray<TTestRec>;
const
ARRAY_A : TArray<string> = ['A1', 'A2', 'A3', 'A4'];
ARRAY_B : TArray<string> = ['B1', 'B2', 'B3'];

ARRAY_C : array[1..2] of TTestRec = (
(X: 'testC1'; Y:1),
(X: 'testC2'; Y:2)
);
ARRAY_D : array[1..3] of TTestRec = (
(X: 'testD1'; Y:3),
(X: 'testD2'; Y:4)
(X: 'testD3'; Y:9)
);
var
Z : TArray<string>;
W : array of TTestRec;
begin
Z := ARRAY_A; // this works
Z := ARRAY_B; // this works

W := ARRAY_C; // this does not work
W := ARRAY_D; // this does not work
end;

最佳答案

正在分配 ARRAY_AARRAY_BZ有效,因为您正在分配 TArray<string> TArray<string> 的常量多变的。它们都是同一类型,因此彼此兼容。

正在分配 ARRAY_CARRAY_DW不起作用,因为您正在将静态数组常量分配给动态数组变量。它们是彼此不兼容的不同类型,如 Delphi 文档中所述:

Type Compatibility and Identity (Delphi)

Type Compatibility

Every type is compatible with itself. Two distinct types are compatible if they satisfy at least one of the following conditions.

  • They are both real types.
  • They are both integer types.
  • One type is a subrange of the other.
  • Both types are subranges of the same type.
  • Both are set types with compatible base types.
  • Both are packed-string types with the same number of characters.
  • One is a string type and the other is a string, packed-string, or Char type.
  • One type is Variant and the other is an integer, real, string, character, or Boolean type.
  • Both are class, class-reference, or interface types, and one type is derived from the other.
  • One type is PAnsiChar or PWideChar and the other is a zero-based character array of the form array[0..n] of PAnsiChar or PWideChar.
  • One type is Pointer (an untyped pointer) and the other is any pointer type.
  • Both types are (typed) pointers to the same type and the {$T+} compiler directive is in effect.
  • Both are procedural types with the same result type, the same number of parameters, and type-identity between parameters in corresponding positions.

Assignment Compatibility

Assignment-compatibility is not a symmetric relation. An expression of type T2 can be assigned to a variable of type T1 if the value of the expression falls in the range of T1 and at least one of the following conditions is satisfied:

  • T1 and T2 are of the same type, and it is not a file type or structured type that contains a file type at any level.
  • T1 and T2 are compatible ordinal types.
  • T1 and T2 are both real types.
  • T1 is a real type and T2 is an integer type.
  • T1 is PAnsiChar, PWideChar, PChar or any string type and the expression is a string constant.
  • T1 and T2 are both string types.
  • T1 is a string type and T2 is a Char or packed-string type.
  • T1 is a long string and T2 is PAnsiChar, PWideChar or PChar.
  • T1 and T2 are compatible packed-string types.
  • T1 and T2 are compatible set types.
  • T1 and T2 are compatible pointer types.
  • T1 and T2 are both class, class-reference, or interface types and T2 is a derived from T1.
  • T1 is an interface type and T2 is a class type that implements T1.
  • T1 is PAnsiChar or PWideChar and T2 is a zero-based character array of the form array[0..n] of Char (when T1 is PAnsiChar) or of WideChar (when T1 is PWideChar).
  • T1 and T2 are compatible procedural types. (A function or procedure identifier is treated, in certain assignment statements, as an expression of a procedural type. See "Procedural types in statements and expression" earlier in this chapter.)
  • T1 is Variant and T2 is an integer, real, string, character, Boolean, interface type or OleVariant type.
  • T1 is an OleVariant and T2 is an integer, real, string, character, Boolean, interface, or Variant type.
  • T1 is an integer, real, string, character, or Boolean type and T2 is Variant or OleVariant.
  • T1 is the IUnknown or IDispatch interface type and T2 is Variant or OleVariant. (The variant's type code must be varEmpty, varUnknown, or varDispatch if T1 is IUnknown, and varEmpty or varDispatch if T1 is IDispatch.)

正在分配 ARRAY_AARRAY_BZ满足“分配兼容性”要求。正在分配 ARRAY_CARRAY_DW没有。

要解决静态数组的问题,您必须改用指针(动态数组已经是指针),例如:

procedure TForm1.Button1Click(Sender: TObject);
type
TTestRec = record
X: string;
Y: Integer;
end;
PTestRec = ^TTestRec;
const
ARRAY_A : TArray<string> = ['A1', 'A2', 'A3', 'A4'];
ARRAY_B : TArray<string> = ['B1', 'B2', 'B3'];

ARRAY_C : array[1..2] of TTestRec = (
(X: 'testC1'; Y:1),
(X: 'testC2'; Y:2)
);
ARRAY_D : array[1..3] of TTestRec = (
(X: 'testD1'; Y:3),
(X: 'testD2'; Y:4)
(X: 'testD3'; Y:9)
);
var
Z : TArray<string>;
W : PTestRec;
begin
Z := ARRAY_A;
Z := ARRAY_B;

W := @ARRAY_C[1];
W := @ARRAY_D[1];
end;

但是请注意,无法从 W 确定本身是否指向 array[1..2] of TTestRecarray[1..3] of TTestRec , 这是两种完全不同的类型。所以,如果你需要使用 W要迭代数组,您必须单独跟踪可接受的边界,例如:

{$POINTERMATH ON}

procedure TForm1.Button1Click(Sender: TObject);
type
TTestRec = record
X: string;
Y: Integer;
end;
PTestRec = ^TTestRec;
const
ARRAY_A : TArray<string> = ['A1', 'A2', 'A3', 'A4'];
ARRAY_B : TArray<string> = ['B1', 'B2', 'B3'];

ARRAY_C : array[1..2] of TTestRec = (
(X: 'testC1'; Y:1),
(X: 'testC2'; Y:2)
);
ARRAY_D : array[1..3] of TTestRec = (
(X: 'testD1'; Y:3),
(X: 'testD2'; Y:4)
(X: 'testD3'; Y:9)
);
var
Z : TArray<string>;
W : PTestRec;
W_Len, I: Integer;
begin
Z := ARRAY_A;
for I := 0 to High(Z) do begin
// use Z[I] as needed ...
end;

Z := ARRAY_B;
for I := 0 to High(Z) do begin
// use Z[I] as needed ...
end;

W := @ARRAY_C[1];
W_Len := Length(ARRAY_C);
for I := 0 to Pred(W_Len) do begin
// use W[I] as needed ...
end;

W := @ARRAY_D[1];
W_Len := Length(ARRAY_D);
for I := 0 to Pred(W_Len) do begin
// use W[I] as needed ...
end;
end;

关于arrays - Delphi - 指向 TRecord 的常量数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66953540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com