Avvertenza: la mia risposta descrive in realtà variabili acquisite diverse dal sollevamento di lambda. Non letto la domanda (è necessario dormire). Ma ho passato un po 'di tempo a scriverlo, quindi sono dispiaciuto di cancellarlo. Lasciato come una comunità WIKI.
Il sollevamento di Lambda, spesso definito come chiusura, è un modo per consentire l'accesso di variabili in ambito all'interno di un'espressione lambda annidata.
È difficile entrare nei dettagli nitidi delle chiusure senza scegliere una lingua particolare. Uno degli effetti collaterali del sollevamento di lambda, in ogni lingua, è che tende ad estendere la durata di una variabile da un ambito locale, di breve durata, a un ambito molto più lungo. Di solito ciò avviene nella forma del trasferimento di una variabile dallo stack all'heap all'interno del compilatore. Questa è un'azione molto specifica del linguaggio e quindi produce implementazioni molto diverse basate sulla lingua.
Mi concentrerò su C# poiché è probabilmente la lingua più comune ai lettori di stack overflow. Iniziamo con il seguente codice.
public Func<int> GetAFunction() {
var x = 42;
Func<int> lambda1 =() => x;
Func<int> lambda2 =() => 42;
...
return lambda1;
}
In questo esempio sono state create 2 espressioni lambda. In entrambi i casi è assegnato a un'istanza delegata di tipo Func. Tutti i delegati in .Net richiedono che una vera funzione li stia sostenendo da qualche parte. Così sotto la cappa, tutte le espressioni lambda/funzioni anonime in C# vengono tradotte in una definizione di metodo.
Generare una funzione per lambda2 è piuttosto semplice. È una funzione isolata che restituisce solo un valore costante.
public static int RealLambda2() {
return 42;
}
Generare lambda1 è un po 'più difficile. Una definizione letterale sarebbe simile al seguente
public static int RealLambda1() {
return x;
}
Questo ovviamente non verrà compilato perché x non è accessibile. Per fare in modo che funzioni, il compilatore C# deve lift la variabile x in una chiusura. Si può quindi restituire un puntatore a una funzione all'interno della chiusura di soddisfare l'espressione delegato
class Closure1 {
int x;
public int RealLambda1() {
return x;
}
}
Questo è un esempio molto semplice ma dovrebbero auspicabilmente dettaglio tecnica di sollevamento. Il diavolo è sfortunatamente nei dettagli e diventa molto più complesso con lo scenario.
Leggere prima le chiusure - http://en.wikipedia.org/wiki/Closure_(computer_science) – dirkgently