2014-05-04 107 views
6

在克里斯的博客: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; 

什麼問題,請問「參考」關鍵字解決,不能用正常的程序來完成類型?

回答

11

隨着reference過程中,您可以使用:

  • 傳統的過程中,或
  • 對象,類或記錄的方法,或
  • 匿名方法。

它與設置reference程序,除了所有其他程序類型的匿名方法的工作能力。除了其他程序或方法類型外,匿名方法設置的是變量捕獲。

有關更詳細的討論,請參閱此答案:What is the difference between of object and reference to?。匿名方法的官方文檔也值得一讀。

4

根據官方文檔,問題(待解決)是匿名方法是託管類型,而程序變量則不是。
'引用'關鍵字比其他過程類型更普遍。

這裏的DOC如此形容: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; 

然而,反過來是不是真正:你不能匿名方法分配給一個普通的方法指針。方法引用是託管類型,但方法指針是非託管類型。因此,出於類型安全的原因,不支持分配方法指針的方法引用。例如,事件是方法指針值的屬性,所以不能對事件使用匿名方法。有關此限制的更多信息,請參閱變量綁定部分。

+1

您錯過了匿名方法中最重要的關鍵特性之一,它是可變捕獲。其他的東西像傳遞或返回它們可以用常規的函數指針來完成,但變量捕獲不能。 –

+0

謝謝@StefanGlienke指出。我忘記了這一切。當然,堆上發生的所有事情都會排除高速代碼中的這些東西。 – Johan