Qualcuno può spiegarmi il significato dell'operatore @
(handle di funzione) e perché utilizzarlo?Che cos'è un handle di funzione e come è utile?
risposta
Il function handle operator in MATLAB agisce essenzialmente come un puntatore a un'istanza specifica di una funzione. Alcune delle altre risposte hanno discusso alcuni dei suoi usi, ma qui aggiungerò un altro uso che spesso ho per questo: mantenere l'accesso a funzioni che non sono più "in ambito".
Ad esempio, la seguente funzione inizializza un valore count
, e quindi restituisce una maniglia funzione a una funzione nidificata increment
:
function fHandle = start_counting(count)
disp(count);
fHandle = @increment;
function increment
count = count+1;
disp(count);
end
end
Poiché la funzione increment
è un nested function, esso può essere utilizzato solo all'interno della funzione start_counting
(ovvero lo spazio di lavoro di start_counting
è il suo "ambito"). Tuttavia, restituendo un handle alla funzione increment
, posso ancora utilizzarlo al di fuori di start_counting
e mantiene ancora l'accesso alle variabili nell'area di lavoro di start_counting
! Che mi permette di fare questo:
>> fh = start_counting(3); % Initialize count to 3 and return handle
3
>> fh(); % Invoke increment function using its handle
4
>> fh();
5
Notate come possiamo mantenere l'incremento conteggio anche se siamo al di fuori della funzione start_counting
. Ma si può fare qualcosa di ancora più interessante chiamando start_counting
di nuovo con un numero diverso e memorizzare la maniglia funzione in un'altra variabile:
>> fh2 = start_counting(-4);
-4
>> fh2();
-3
>> fh2();
-2
>> fh(); % Invoke the first handle to increment
6
>> fh2(); % Invoke the second handle to increment
-1
Si noti che questi due contatori diversi operano in modo indipendente. La funzione gestisce fh
e fh2
in diverse istanze della funzione increment
con aree di lavoro diverse contenenti valori univoci per count
.
In aggiunta a quanto sopra, l'utilizzo di handle di funzione in combinazione con funzioni annidate può anche aiutare a semplificare la progettazione della GUI, come illustrato in this other SO post.
Esonero di responsabilità: il codice non testato ...
L'operatore maniglia funzione consente di creare un riferimento a una funzione e passare in giro, proprio come qualsiasi altra variabile:
% function to add two numbers
function total = add(first, second)
total = first + second;
end
% this variable now points to the add function
operation = @add;
Una volta che hai ha ottenuto una maniglia funzione, è possibile richiamare proprio come una normale funzione:
operation(10, 20); % returns 30
una cosa bella di funzione gestisce è che si può passare in giro come qualsiasi OTH er i dati, in modo da poter scrivere funzioni che agiscono su altre funzioni. Questo spesso permette di separare facilmente fuori logica di business:
% prints hello
function sayHello
disp('hello world!');
end
% does something five times
function doFiveTimes(thingToDo)
for idx = 1 : 5
thingToDo();
end
end
% now I can say hello five times easily:
doFiveTimes(@sayHello);
% if there's something else I want to do five times, I don't have to write
% the five times logic again, only the operation itself:
function sayCheese
disp('Cheese');
end
doFiveTimes(@sayCheese);
% I don't even need to explicitly declare a function - this is an
% anonymous function:
doFiveTimes(@() disp('do something else'));
Il Matlab documentation ha una descrizione più completa della sintassi Matlab, e descrive alcuni altri usi per la funzione di guida come callback grafiche.
Le maniglie di funzione sono uno strumento estremamente potente in MATLAB. Un buon inizio è leggere l'aiuto online, che ti darà molto più di me. Al prompt dei comandi, digitare
doc function_handle
Un handle di funzione è un modo semplice per creare una funzione in una riga. Ad esempio, supponiamo di voler integrare numericamente la funzione sin (k * x), dove k ha un valore fisso, esterno. Potrei usare una funzione inline, ma una maniglia di funzione è molto più ordinata. Definire una funzione
k = 2;
fofx = @(x) sin(x*k);
Vedere che ora è possibile valutare la funzione fofx nella riga di comando. MATLAB sa cos'è k, quindi ora possiamo usare fofx come funzione.
fofx(0.3)
ans =
0.564642473395035
In effetti, possiamo passare fofx in giro, efficacemente come variabile. Ad esempio, consente di chiamare quad per eseguire l'integrazione numerica. Prenderò l'intervallo [0, pi/2].
quad(fofx,0,pi/2)
ans =
0.999999998199215
Come si può vedere, quad ha fatto l'integrazione numerica. (A proposito, una funzione inline sarebbe stato almeno un ordine di magitude più lento, e molto meno facile da lavorare.)
x = linspace(0,pi,1000);
tic,y = fofx(x);toc
Elapsed time is 0.000493 seconds.
A titolo di confronto, provare una funzione inline.
finline = inline('sin(x*k)','x','k');
tic,y = finline(x,2);toc
Elapsed time is 0.002546 seconds.
Una cosa semplice di una maniglia funzione è che si può definire al volo. Ridurre al minimo la funzione cos (x), nell'intervallo [0,2 * pi]?
xmin = fminbnd(@(x) cos(x),0,2*pi)
xmin =
3.14159265358979
Ci sono molti, molti altri usi per le funzioni in MATLAB. Ho solo graffiato la superficie qui.
- 1. Quale funzione di gc_collect_cycles è utile?
- 2. Che cosa è std :: ref utile in questa funzione?
- 3. Matlab - Controllare se la funzione handle è una funzione particolare o un tipo di funzione
- 4. Come determinare se un handle di file Perl è un handle di lettura o scrittura?
- 5. La funzione div è utile (stdlib.h)?
- 6. Nome funzione generatore Python - è un prefisso utile?
- 7. Che cos'è un handle di evento?
- 8. Che cosa è utile per un parametro reference-to-array?
- 9. Come capire se un handle di file è un socket?
- 10. Perché match.call è utile?
- 11. Quando è utile un ConcurrentSkipListSet?
- 12. È stato sempre utile?
- 13. Cos'è il Mago e in che modo è utile?
- 14. Come usare e quando è utile usare memmove in C?
- 15. Che cos'è un handle in C++?
- 16. La funzione Rota_di_ricerca di Rails è davvero utile?
- 17. auto_ptr, immediato get() e release() - è utile?
- 18. Perché l'attivazione e-mail è utile?
- 19. È utile il guadagno?
- 20. Come distinguere un handle di socket Win32 da altri handle di pipe?
- 21. Come può essere utile sovraccaricare l'operatore "chiamata di funzione"?
- 22. Come convertire la stringa in handle di funzione in Matlab?
- 23. Quando è utile digitare manifest di sqlite?
- 24. zero è mai un handle valido?
- 25. Quando è utile __proto__?
- 26. Quando è utile un filtro Bloom?
- 27. è jquery. È sempre utile?
- 28. PyWinAuto è ancora utile?
- 29. MVVM è davvero utile?
- 30. Perché std :: equal_to è utile?
Una cosa importante da notare è che le funzioni create con la parola chiave function e le funzioni create dall'operatore @ hanno regole di scoping diverse. hGetCount = @ getCount; funzione c = getCount; c = count; fine; fa la ricerca della variabile count al momento della valutazione (usando scope lessicale), come descritto sopra. La funzione hGetCount = @() conta; avrà il valore della variabile di conteggio sostituita al momento della creazione. –
Gli handle di funzione consentono di lavorare con funzioni o sottofunzioni annidate, al di fuori della funzione principale. Possono aiutarti nella programmazione della GUI. –
@ Mr. Fooz: buon punto! Le funzioni anonime create con l'operatore @ sostituiranno semplicemente i valori per le variabili esistenti nello spazio di lavoro nel momento in cui vengono create, mentre le funzioni "normali" hanno le proprie aree di lavoro per l'archiviazione delle variabili. – gnovice