2014-05-04 2 views
6

Sur le blog de Chris: http://delphihaven.wordpress.com/2011/07/14/weird-in-more-ways-than-one/Quelle question fait « référence à » résoudre

Je trouve le code suivant

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; 

Quel problème la « référence » mot-clé à résoudre qui ne peut être fait avec une procédure normale type?

Répondre

11

Avec une procédure reference vous pouvez utiliser:

  • Une procédure traditionnelle, ou
  • Une méthode d'un objet, classe ou un enregistrement, ou
  • Une méthode anonyme.

C'est la capacité de travailler avec des méthodes anonymes qui définit les procédures reference en dehors de tous les autres types de procédures. Et ce qui distingue les méthodes anonymes des autres types de procédures ou de méthodes est la capture de variables.

Pour une discussion plus détaillée, référez-vous à cette réponse: What is the difference between of object and reference to?. La documentation officielle pour les méthodes anonymes vaut également la peine d'être lue.

4

Selon la documentation officielle, le problème (à résoudre) est que les méthodes anonymes sont des types gérés, alors que les variables procédurales ne le sont pas.
Le mot-clé 'référence à' est plus général que les autres types de procédures.

Voilà comment le doc met: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html

Les méthodes anonymes sont généralement attribuées à quelque chose, comme dans ces exemples:

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

myProc := procedure(x: Integer) 
begin 
    Writeln(x); 
end; 

Les méthodes anonymes peuvent également être retournées par des fonctions ou passé en tant que valeurs pour les paramètres lors de l'appel de méthodes. Par exemple, en utilisant la méthode myFunc variables anonyme défini juste au-dessus:

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;) 

références de méthode peuvent également être affectés à des méthodes ainsi que des méthodes anonymes. Par exemple:

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; 

Cependant, l'inverse est vrai pas: vous ne pouvez pas attribuer une méthode anonyme à un pointeur régulier de la méthode. Les références de méthode sont des types gérés, mais les pointeurs de méthode sont des types non gérés. Ainsi, pour des raisons de sécurité de type, l'affectation de références de méthode aux pointeurs de méthode n'est pas prise en charge. Par exemple, les événements sont des propriétés de type pointeur, donc vous ne pouvez pas utiliser une méthode anonyme pour un événement. Voir la section sur la liaison de variables pour plus d'informations sur cette restriction.

+1

Il vous manque l'une des fonctionnalités clés les plus importantes des méthodes anonymes qui est la capture de variables. D'autres choses comme les faire circuler ou les renvoyer peuvent être faites avec des pointeurs de fonction réguliers mais la capture de variables ne le peut pas. –

+0

Merci @StefanGlienke pour le signaler. J'avais oublié tout ça. Bien sûr, toute cette fantaisie qui se passe sur le tas exclut ce genre de choses pour le code haute vitesse. – Johan

Questions connexes