Delphi ';无法捕获符号';在匿名方法中使用打开的数组参数时出错,该方法传递给另一个函数
我试图在作为参数传递给另一个函数的匿名方法中使用Integer参数的Delphi ';无法捕获符号';在匿名方法中使用打开的数组参数时出错,该方法传递给另一个函数,delphi,compiler-errors,delphi-xe7,anonymous-methods,Delphi,Compiler Errors,Delphi Xe7,Anonymous Methods,我试图在作为参数传递给另一个函数的匿名方法中使用Integer参数的数组: type TAnonymousMethod = reference to procedure(); procedure SubTest(AMethod : TAnonymousMethod); begin AMethod(); end; procedure Test(ACodes : array of Integer); begin SubTest( procedure() begin
数组:
type
TAnonymousMethod = reference to procedure();
procedure SubTest(AMethod : TAnonymousMethod);
begin
AMethod();
end;
procedure Test(ACodes : array of Integer);
begin
SubTest(
procedure()
begin
ShowMessage(IntToStr(Length(ACodes)));
end
);
end;
编译时会产生以下E2555错误:
[dcc32错误]单元1.pas(38):E2555无法捕获符号“ACodes”
我试着只使用一个Integer
值来做同样的事情,并且编译时没有错误
procedure Test(ACode : Integer);
begin
SubTest(
procedure()
begin
ShowMessage(IntToStr(ACode));
end
);
end;
因此,问题似乎只与开放数组参数有关
为什么会发生这种情况以及如何避免这种情况?开放数组实际上是作为两个参数实现的,第一个是指向第一个元素的指针,第二个是最高索引
知道了这一点,就很清楚为什么不能捕获这样的东西,因为捕获的价值可能会超过原始生命周期
是的,您可以捕获由于被捕获而可能超过其生命周期的其他对象,但在这些情况下,这是因为您显式地销毁了一个对象,或者释放了一些内存,但不是因为它是如何传递给某个例程的。捕获始终确保值至少在闭包存在的同时保持活动状态
闭包中捕获的值在内部实现为编译器创建的闭包支持对象中的字段,因此基本上有一个从捕获的值到这些字段的赋值(简单地说)。无法将打开的数组参数分配给局部变量或类似变量,只能像数组一样访问或进一步传递。您的匿名类型声明是错误的。您应该向接受此参数类型的过程声明此类型。就像我的示例中的TFoo
。它正在工作:
单元1.pas:
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TFoo = reference to procedure ( ints_ : array of integer );
TForm3 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
fFoo : TFoo;
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure fooCaller( foo_ : TFoo );
begin
foo_( [1,2,3] );
end;
procedure fooCaller2( foo_ : TFoo; ints_ : array of integer );
begin
foo_( ints_ );
end;
procedure TForm3.Button1Click(Sender: TObject);
begin
fooCaller(
procedure ( ints_ : array of integer )
var
i : integer;
begin
i := length( ints_ );
end );
// OR
fooCaller2(
procedure ( ints_ : array of integer )
var
i : integer;
begin
i := length( ints_ );
end, [1,2,3] );
end;
end.
单元1.dfm:
object Form3: TForm3
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 411
ClientWidth = 852
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 288
Top = 72
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
end
首先将Length(ACodes)
或IntToStr(Length(ACodes))
保存为Test
中的局部变量,并在匿名方法中使用此局部变量就足够了吗?请注意,如果使用TArray
而不是开放数组,则捕获工作正常。Embarcadero更详细地解释了实际的捕获机制。