Ecco quello che penso sia un esempio super semplice di passare qualcosa per nome:
// JavaScript
function apply(a, b, f) { return f(a,b); }
function add(a,b) { return a + b; }
var result = apply(2, 4, add); // result is now 6
// The same in C using function-pointers
int apply(int a, int b, int (*f)(int,int)) { return f(a,b); }
int add(int a, int b) { return a + b; }
int result = apply(2, 4, add); // result is once again 6
Notate come sto passando il nome della funzione add
come parametro nella funzione apply
, proprio come farei con qualsiasi altra variabile. La funzione f
non viene valutata al momento della dichiarazione, semplicemente perché non può essere valutata; il suo corpo non esiste alla dichiarazione. Ma questo apre a così tante possibilità in termini di riduzione del codice di caldaia. Come dire, hai 2 funzioni / metodi che entrambi fanno esattamente la stessa cosa, a parte una sola linea molto specifica; invece di dover scrivere esattamente la stessa cosa due volte, puoi scriverlo una volta e poi passare la riga di codice che spicca, per nome.
Lascia che ti mostri un esempio più elaborato di uno dei miei progetti:
// C# snippet from a web-communication utility
private static void PostHelper(string inputUri, Action<WebClient, Uri> clientFunction) {
var client = new WebClient();
client.Headers[HttpRequestHeader.ContentType] = "application/json";
var uri = new Uri(inputUri);
clientFunction(client, uri);
}
public static void Post(string inputUri, string jsonInput) {
PostHelper(inputUri, (client, uri) => client.UploadString(uri, "POST", jsonInput));
}
public static void PostAsync(string inputUri, string jsonInput) {
PostHelper(inputUri, (client, uri) => client.UploadStringAsync(uri, "POST", jsonInput));
}
Se non avessi usato la capacità di C # di passare per nome, sotto forma di funzioni di ordine superiore, avrei dovuto scrivere il codice in PostHelper
due volte, con la modifica minore che si dice UploadString
, e l'altro dice UploadStringAsync
, facendo come se l'avessi salvato codice ripetuto, e mi consente anche di espanderlo più tardi se voglio aggiungere più varianti del metodo. Poiché clientFunction
è valutato pigramente, posso rendere il mio codice molto più scalabile.