40

和有什么区别

TFuncOfIntToString = reference to function(x: Integer): string; 

TFuncOfIntToString = function(x: Integer): string of object; 

我使用对象

4

2 回答 2

92

让我们考虑以下三种类型声明:

TProcedure = procedure;
TMethod = procedure of object;
TAnonMethod = reference to procedure;

这些都非常相似。就这三种类型的调用实例而言,调用代码是相同的。不同之处在于可以分配给这些类型的变量的内容。

程序类型

TProcedure是一种程序类型TProcedure您可以将以下形式的东西分配给类型的变量:

procedure MyProcedure;
begin
end;

这是一个非面向对象的过程。您不能将实例或类方法分配给TProcedure变量。但是,您可以将静态类方法分配给TProcedure变量。

方法指针

TMethod是一个方法指针。这由 的存在表示of object。当您有一个类型的变量时,TMethod您必须分配:

  1. 实例化对象的实例方法,或
  2. 一个类方法。

因此,您可以分配以下任一项:

procedure TMyClass.MyMethod;
begin
end;

class procedure TMyClass.MyClassMethod;
begin
end;

过程类型和方法指针之间的最大区别在于后者包含对代码和数据的引用。方法指针通常称为两指针过程类型。包含方法指针的变量包含对代码和调用它的实例/类的引用。

考虑以下代码:

var
  instance1, instance2: TMyClass;
  method1, method2: TMethod;
....
method1 := instance1.MyMethod;
method2 := instance2.MyMethod;

现在,虽然method1method2引用同一段代码,但它们与不同的对象实例相关联。所以,如果我们打电话

method1();
method2();

我们正在调用MyMethod两个不同的实例。该代码相当于:

instance1.MyMethod();
instance2.MyMethod();

匿名方法

最后我们来看看匿名方法。这些甚至比过程类型和方法指针更通用。您可以将以下任何内容分配给使用以下reference to语法定义的变量:

  1. 一个普通的非面向对象的过程。
  2. 实例化类的实例方法。
  3. 一个类方法。
  4. 一种匿名方法。

例如:

var
  AnonMethod: TAnonMethod;
....
AnonMethod := MyProcedure;            // item 1 above
AnonMethod := instance1.MyMethod;     // item 2
AnonMethod := TMyClass.MyClassMethod; // item 3

匿名方法(上面的第 4 项)是在您的代码中内联声明的方法。例如:

var
  AnonMethod: TAnonMethod;
....
AnonMethod := procedure
  begin
    DoSomething;
  end;

与过程类型和方法指针相比,匿名方法的最大好处是它们允许捕获变量。例如考虑以下简短的程序来说明:

{$APPTYPE CONSOLE}
program VariableCapture;

type
  TMyFunc = reference to function(X: Integer): Integer;

function MakeFunc(Y: Integer): TMyFunc;
begin
  Result := function(X: Integer): Integer
    begin
      Result := X*Y;
    end;
end;

var
  func1, func2: TMyFunc;

begin
  func1 := MakeFunc(3);
  func2 := MakeFunc(-42);
  Writeln(func1(4));
  Writeln(func2(2));
  Readln;
end.

这具有以下输出:

12
-84
于 2013-02-20T09:10:33.833 回答
8

第一种是匿名方法,第二种是普通方法

于 2013-02-20T08:39:04.813 回答