Arrays 从函数返回动态数组
我和Delphi 7一起工作 这是我的基础课。函数load\u for_edit()应该返回一个字符串数组,听起来像这样。问题不在这里,而是更进一步Arrays 从函数返回动态数组,arrays,delphi,delphi-7,Arrays,Delphi,Delphi 7,我和Delphi 7一起工作 这是我的基础课。函数load\u for_edit()应该返回一个字符串数组,听起来像这样。问题不在这里,而是更进一步 ... type TStringArray = array of string; ... function load_for_edit(): TStringArray; ... numberOfFields: integer; ... function TBaseForm.loa
...
type
TStringArray = array of string;
...
function load_for_edit(): TStringArray;
...
numberOfFields: integer;
...
function TBaseForm.load_for_edit(): TStringArray;
var
query: TADOQuery;
i: integer;
begin
query := TADOQuery.Create(self);
query.Connection := DataModule1.ADOConnection;
query.SQL.Add('CALL get_' + self.table_name + '_id(' + self.id + ')');
query.Open;
numberOfFields := query.Fields.Count;
SetLength(result, query.Fields.Count);
for i := 0 to query.Fields.Count - 1 do
result[i] := query.Fields[i].Value.AsString;
end;
下一个类是基类的后代,它试图从基类的load\u for\u edit()函数接收数组
...
type
TStringArray = array of string;
...
procedure TPublisherEditForm.FormShow(Sender: TObject);
var
rec: TStringArray;
begin
inherited;
SetLength(rec, self.numberOfFields);
rec := load_for_edit(); // Compilation stops here
end;
但是,应用程序不会编译。Delphi发出以下错误消息:
Incompatible types
因此,这意味着函数load\u for_edit()返回的数据类型与变量rec的数据类型不同,尽管从它们各自的类型声明部分可以看出,它们的声明是完全相同的。我不知道这里发生了什么,该怎么办。请帮我想出一个解决方案。您有两个单独的
tstringaray
(每个单元一个)声明,它们是不同的。(它们位于两个独立的单元中,这一事实使它们有所不同。UnitA.tstringaray
与UnitB.tstringaray
不同,即使它们都声明为type tstringaray=string数组;
)
您需要使用单个类型声明:
unit
BaseFormUnit;
interface
uses
...
type
TStringArray: array of string;
TBaseForm = class(...)
numberOfFields: Integer;
function load_for_edit: TStringArray;
end;
implementation
// Not sure here. It looks like you should use a try..finally to
// free the query after loading, but if you need to use it later
// to save the edits you should create it in the TBaseForm constructor
// and free it in the TBaseForm destructor instead, which means it
// should also be a field of the class declaration above.
function TBaseForm.load_for_edit(): TStringArray;
var
query: TADOQuery;
i: integer;
begin
query := TADOQuery.Create(self);
query.Connection := DataModule1.ADOConnection;
query.SQL.Add('CALL get_' + self.table_name + '_id(' + self.id + ')');
query.Open;
numberOfFields := query.Fields.Count;
SetLength(result, numberOfFields);
for i := 0 to numberOfFields - 1 do
Result[i] := query.Fields[i].Value.AsString;
end;
...
end.
现在您的子类可以访问它了:
unit
PublisherEditFormUnit;
interface
uses
... // Usual Forms, Windows, etc.
BaseFormUnit;
type
TPublisherEditForm = class(TBaseForm)
...
procedure FormShow(Sender: TObject);
end;
implementation
procedure TPublisherEditForm.FormShow(Sender: TObject);
var
rec: TStringArray;
begin
// No need to call SetLength - the base class does.
rec := load_for_edit(); // Compilation stops here
end;
...
end.
关于双重声明是问题所在,您是正确的,但您的示例是错误的。在您的示例中,
TPublisherEditForm
不是从TBaseForm
派生出来的,但在Mikhail的情况下是这样的。这就不同了,因为TStringArray
不需要在一个单独的单元中。它可以在TBaseForm
单元中声明,然后TPublisherEditForm
将有权访问tstringaray
,因为它必须使用TBaseForm
单元。@Remy:谢谢,我错过了。重写示例来说明这一点,并更正文本。这种类型标识是另一个问题,它使TArray在现代Delphi中非常有用。我所知道的几乎所有语言都是强类型的,甚至像Python这样的动态语言。在这种情况下,类型兼容性给程序员带来了不便。为了让泛型在任何时候都有用,TArray的类型兼容性规则必须是特殊的。事实上,所有泛型类型都有特殊的兼容性规则。当dmitry到达时,可能会有人批评他。@Lucas:它可以很好地处理记录数组。我无法解释为什么你的代码不起作用,因为我看不到它。