Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi ';无法捕获符号';在匿名方法中使用打开的数组参数时出错,该方法传递给另一个函数_Delphi_Compiler Errors_Delphi Xe7_Anonymous Methods - Fatal编程技术网

Delphi ';无法捕获符号';在匿名方法中使用打开的数组参数时出错,该方法传递给另一个函数

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

我试图在作为参数传递给另一个函数的匿名方法中使用Integer参数的
数组:

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更详细地解释了实际的捕获机制。