【问题标题】:What issue does "reference to" solve“参考”解决了什么问题
【发布时间】:2014-06-21 02:45:51
【问题描述】:

在克里斯的博客上:http://delphihaven.wordpress.com/2011/07/14/weird-in-more-ways-than-one/

我找到了以下代码

type
  TLinkVisitor<T> = reference to procedure(const Item: T);

  TDoubleLinked<T> = record
    Prev: ^TDoubleLinked<T>;
    Next: ^TDoubleLinked<T>;
    Value: T;
    class function Create(const aValue: T): Pointer; static;
    function Add(const aValue: T): Pointer;
    procedure Delete;
    procedure DeleteAll;
    function First: Pointer;
    function Last: Pointer;
    procedure ForEach(const Proc: TLinkVisitor<T>);
  end;

'reference to' 关键字解决了哪些问题是普通程序类型无法解决的?

【问题讨论】:

    标签: delphi generics anonymous-methods


    【解决方案1】:

    您可以使用reference 过程:

    • 传统程序,或
    • 对象、类或记录的方法,或
    • 匿名方法。

    使用匿名方法的能力将reference 过程与所有其他过程类型区分开来。将匿名方法与其他过程或方法类型区分开来的是变量捕获。

    有关更详细的讨论,请参阅此答案:What is the difference between of object and reference to?。匿名方法的官方文档也值得一读。

    【讨论】:

      【解决方案2】:

      根据官方文档,问题(待解决)是匿名方法是托管类型,而过程变量不是。
      'reference to' 关键字比其他过程类型更通用。

      文档是这样说的:http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html

      匿名方法通常分配给某些东西,如以下示例所示:

      myFunc := function(x: Integer): string
      begin
        Result := IntToStr(x);
      end;
      
      myProc := procedure(x: Integer)
      begin
        Writeln(x);
      end;
      

      匿名方法也可以由函数返回或在调用方法时作为参数值传递。例如,使用上面定义的匿名方法变量 myFunc:

      type
        TFuncOfIntToString = reference to function(x: Integer): string; 
      
      procedure AnalyzeFunction(proc: TFuncOfIntToString); 
      begin 
        { some code } 
      end;
      
      // Call procedure with anonymous method as parameter 
      // Using variable: 
      AnalyzeFunction(myFunc);
      
      // Use anonymous method directly: 
      AnalyzeFunction(function(x: Integer): string 
      begin 
        Result := IntToStr(x); 
      end;) 
      

      方法引用也可以分配给方法以及匿名方法。例如:

      type
        TMethRef = reference to procedure(x: Integer);
      TMyClass = class
        procedure Method(x: Integer);
      end;
      
      var
        m: TMethRef;
        i: TMyClass;
      begin
        // ...
        m := i.Method;   //assigning to method reference
      end;
      

      但是,反过来不是正确的:你不能将匿名方法分配给常规方法指针。方法引用是托管类型,但方法指针是非托管类型。因此,出于类型安全的原因,不支持将方法引用分配给方法指针。例如,事件是方法指针值的属性,因此您不能对事件使用匿名方法。有关此限制的更多信息,请参阅变量绑定部分。

      【讨论】:

      • 您缺少匿名方法最重要的关键特性之一,即变量捕获。传递或返回它们等其他事情可以通过常规函数指针完成,但变量捕获不能。
      • 感谢@StefanGlienke 指出这一点。我已经忘记了这一切。当然,堆上发生的所有这些奇思妙想都排除了这些东西用于高速代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 2010-09-21
      • 1970-01-01
      • 2015-11-12
      • 2011-04-06
      • 2019-12-29
      • 2011-01-21
      相关资源
      最近更新 更多