为什么Delphi编译器总是挑剔我的数组类型,哪怕它们都是兼容的?

2026-04-10 02:341阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计684个文字,预计阅读时间需要3分钟。

为什么Delphi编译器总是挑剔我的数组类型,哪怕它们都是兼容的?

在Windows目标Delphi应用程序中,对象是否通过引用计数,以及其目的,以及动态数组和内存管理在Delphi中的情况。以下是对这两个类的简要描述:

1. TGenericHoldingSummary类: - 这是一个用于存储和汇总特定数据的类。 - 它可能包含方法来添加、删除和查询数据。

2. TGenericHoldingResult类: - 这是一个用于处理查询结果的类。 - 它可能包含方法来处理数据集,如过滤、排序和转换。

(编辑:这是继 Are objects reference counted in Windows-targeted Delphi applications, and if so, what is its purpose?和 Dynamic arrays and memory management in Delphi之后).

我有两个类(TGenericHoldingSummary,TGenericHoldingResultSet)和一个记录(TGenericHoldingResult).

> TGenericHoldingSummary包含单个TGenericHoldingResultSet,如果需要,可以从数据库设置为nil和lazy-loaded.
> TGenericHoldingResultSet包含TGenericHoldingResult记录的动态数组.

在下面,错误是在TGenericHoldingResultSet构造函数中的赋值.

TGenericHoldingResult = record code : Integer; level : String; msg : String; end; TGenericHoldingResultSet = class(TObject) public // Lifecycle constructor Create(parent : TGenericHoldingSummary; resArr : Array of TGenericHoldingResult); destructor Destroy; // Accessors function ResultCount() : Integer; function Result(i : Integer) : TGenericHoldingResult; private // Variables summary : TGenericHoldingSummary; resultArray : Array of TGenericHoldingResult; end; TGenericHoldingSummary = class(TObject) public // Note that the summary object 'owns' the results, and deallocates // its memory in the destructor. function getResultSet: TGenericHoldingResultSet; private // Member variables resultSet: TGenericHoldingResultSet; end; // Note that the summary object 'owns' the results, and deallocates // its memory in the destructor. function TGenericHoldingSummary.getResultSet() : TGenericHoldingResultSet; var sql : String; i : Integer; resultArray : Array of TGenericHoldingResult; begin if resultSet = nil then begin // Get results via SQL. SetLength(resultArray, holding.clientDataSet.RecordCount); for i := 0 to holding.clientDataSet.RecordCount - 1 do begin resultArray[i].code := holding.clientDataSet.FieldByName('code').AsInteger; resultArray[i].level := holding.clientDataSet.FieldByName('level').AsString; resultArray[i].msg := holding.clientDataSet.FieldByName('message').AsString; end; resultSet := TGenericHoldingResultSet.Create(self, resultArray); end; result := resultSet; end; // Lifecycle constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; resArr : Array of TGenericHoldingResult); begin summary := parent; // The following *should* work, shouldn't it? // E.g., seeing as dynamic arrays a reference counted in Delphi for // all platforms, this should simply increment the reference count. resultArray := resArr; end;

错误如下:

[DCC Error] GenericHolding.pas(302): E2010 Incompatible types: 'Dynamic array' and 'Array' 您无法将打开的数组分配给动态数组.见 Open Array Parameters.

Note: The syntax of open array parameters resembles that of dynamic array types, but they do not mean the same thing. The previous example creates a function that takes any array of Char elements, including (but not limited to) dynamic arrays. To declare parameters that must be dynamic arrays, you need to specify a type identifier:

type TDynamicCharArray = array of Char; function Find(const A: TDynamicCharArray): Integer;

可以在此处找到开放阵列的用例以及与动态阵列的不同之处的一个很好的总结:Open array parameters.

如果您有支持泛型的Delphi版本,则可以声明构造函数头:

constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; const resArr : TArray<TGenericHoldingResult>);

和您的resultArray为TArray< TGenericHoldingResult>.

为什么Delphi编译器总是挑剔我的数组类型,哪怕它们都是兼容的?

这将避免必须为数组声明特定类型.

正如David所指出的,开放阵列具有一个优势,因为它们具有更广泛的用例,并且应该尽可能使用.

本文共计684个文字,预计阅读时间需要3分钟。

为什么Delphi编译器总是挑剔我的数组类型,哪怕它们都是兼容的?

在Windows目标Delphi应用程序中,对象是否通过引用计数,以及其目的,以及动态数组和内存管理在Delphi中的情况。以下是对这两个类的简要描述:

1. TGenericHoldingSummary类: - 这是一个用于存储和汇总特定数据的类。 - 它可能包含方法来添加、删除和查询数据。

2. TGenericHoldingResult类: - 这是一个用于处理查询结果的类。 - 它可能包含方法来处理数据集,如过滤、排序和转换。

(编辑:这是继 Are objects reference counted in Windows-targeted Delphi applications, and if so, what is its purpose?和 Dynamic arrays and memory management in Delphi之后).

我有两个类(TGenericHoldingSummary,TGenericHoldingResultSet)和一个记录(TGenericHoldingResult).

> TGenericHoldingSummary包含单个TGenericHoldingResultSet,如果需要,可以从数据库设置为nil和lazy-loaded.
> TGenericHoldingResultSet包含TGenericHoldingResult记录的动态数组.

在下面,错误是在TGenericHoldingResultSet构造函数中的赋值.

TGenericHoldingResult = record code : Integer; level : String; msg : String; end; TGenericHoldingResultSet = class(TObject) public // Lifecycle constructor Create(parent : TGenericHoldingSummary; resArr : Array of TGenericHoldingResult); destructor Destroy; // Accessors function ResultCount() : Integer; function Result(i : Integer) : TGenericHoldingResult; private // Variables summary : TGenericHoldingSummary; resultArray : Array of TGenericHoldingResult; end; TGenericHoldingSummary = class(TObject) public // Note that the summary object 'owns' the results, and deallocates // its memory in the destructor. function getResultSet: TGenericHoldingResultSet; private // Member variables resultSet: TGenericHoldingResultSet; end; // Note that the summary object 'owns' the results, and deallocates // its memory in the destructor. function TGenericHoldingSummary.getResultSet() : TGenericHoldingResultSet; var sql : String; i : Integer; resultArray : Array of TGenericHoldingResult; begin if resultSet = nil then begin // Get results via SQL. SetLength(resultArray, holding.clientDataSet.RecordCount); for i := 0 to holding.clientDataSet.RecordCount - 1 do begin resultArray[i].code := holding.clientDataSet.FieldByName('code').AsInteger; resultArray[i].level := holding.clientDataSet.FieldByName('level').AsString; resultArray[i].msg := holding.clientDataSet.FieldByName('message').AsString; end; resultSet := TGenericHoldingResultSet.Create(self, resultArray); end; result := resultSet; end; // Lifecycle constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; resArr : Array of TGenericHoldingResult); begin summary := parent; // The following *should* work, shouldn't it? // E.g., seeing as dynamic arrays a reference counted in Delphi for // all platforms, this should simply increment the reference count. resultArray := resArr; end;

错误如下:

[DCC Error] GenericHolding.pas(302): E2010 Incompatible types: 'Dynamic array' and 'Array' 您无法将打开的数组分配给动态数组.见 Open Array Parameters.

Note: The syntax of open array parameters resembles that of dynamic array types, but they do not mean the same thing. The previous example creates a function that takes any array of Char elements, including (but not limited to) dynamic arrays. To declare parameters that must be dynamic arrays, you need to specify a type identifier:

type TDynamicCharArray = array of Char; function Find(const A: TDynamicCharArray): Integer;

可以在此处找到开放阵列的用例以及与动态阵列的不同之处的一个很好的总结:Open array parameters.

如果您有支持泛型的Delphi版本,则可以声明构造函数头:

constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; const resArr : TArray<TGenericHoldingResult>);

和您的resultArray为TArray< TGenericHoldingResult>.

为什么Delphi编译器总是挑剔我的数组类型,哪怕它们都是兼容的?

这将避免必须为数组声明特定类型.

正如David所指出的,开放阵列具有一个优势,因为它们具有更广泛的用例,并且应该尽可能使用.