Can somebody explain to me the meaning of the @
(function handle) operator and why to use it?
问题:
回答1:
The function handle operator in MATLAB acts essentially like a pointer to a specific instance of a function. Some of the other answers have discussed a few of its uses, but I'll add another use here that I often have for it: maintaining access to functions that are no longer "in scope".
For example, the following function initializes a value count
, and then returns a function handle to a nested function increment
:
function fHandle = start_counting(count)
disp(count);
fHandle = @increment;
function increment
count = count+1;
disp(count);
end
end
Since the function increment
is a nested function, it can only be used within the function start_counting
(i.e. the workspace of start_counting
is its "scope"). However, by returning a handle to the function increment
, I can still use it outside of start_counting
, and it still retains access to the variables in the workspace of start_counting
! That allows me to do this:
>> fh = start_counting(3); % Initialize count to 3 and return handle
3
>> fh(); % Invoke increment function using its handle
4
>> fh();
5
Notice how we can keep incrementing count even though we are outside of the function start_counting
. But you can do something even more interesting by calling start_counting
again with a different number and storing the function handle in another variable:
>> 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
Notice that these two different counters operate independently. The function handles fh
and fh2
point to different instances of the function increment
with different workspaces containing unique values for count
.
In addition to the above, using function handles in conjunction with nested functions can also help streamline GUI design, as I illustrate in this other SO post.
回答2:
Function handles are an extremely powerful tool in matlab. A good start is to read the online help, which will give you far more than I can. At the command prompt, type
doc function_handle
A function handle is a simple way to create a function in one line. For example, suppose I wished to numerically integrate the function sin(k*x), where k has some fixed, external value. I could use an inline function, but a function handle is much neater. Define a function
k = 2;
fofx = @(x) sin(x*k);
See that I can now evaluate the function fofx at the command line. MATLAB knows what k is, so we can use fofx as a function now.
fofx(0.3)
ans =
0.564642473395035
In fact, we can pass fofx around, effectively as a variable. For example, lets call quad to do the numerical integration. I'll pick the interval [0,pi/2].
quad(fofx,0,pi/2)
ans =
0.999999998199215
As you can see, quad did the numerical integration. (By the way, an inline function would have been at least an order of magitude slower, and far less easy to work with.)
x = linspace(0,pi,1000);
tic,y = fofx(x);toc
Elapsed time is 0.000493 seconds.
By way of comparison, try an inline function.
finline = inline('sin(x*k)','x','k');
tic,y = finline(x,2);toc
Elapsed time is 0.002546 seconds.
A neat thing about a function handle is you can define it on the fly. Minimize the function cos(x), over the interval [0,2*pi]?
xmin = fminbnd(@(x) cos(x),0,2*pi)
xmin =
3.14159265358979
There are many, many other uses for function handles in MATLAB. I've only scratched the surface here.
回答3:
Disclaimer: code not tested...
The function handle operator allows you to create a reference to a function and pass it around just like any other variable:
% function to add two numbers
function total = add(first, second)
total = first + second;
end
% this variable now points to the add function
operation = @add;
Once you've got a function handle, you can invoke it just like a regular function:
operation(10, 20); % returns 30
One nice thing about function handles is that you can pass them around just like any other data, so you can write functions that act on other functions. This often allows you to easily separate out business logic:
% 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'));
The Matlab documentation has a fuller description of the Matlab syntax, and describes some other uses for function handles like graphics callbacks.