38

有人可以向我解释@(函数句柄)运算符的含义以及为什么要使用它吗?

4

3 回答 3

50

MATLAB 中的函数句柄运算符的作用本质上类似于指向函数特定实例的指针。其他一些答案已经讨论了它的一些用途,但我将在这里添加我经常使用的另一个用途:维护对不再“在范围内”的函数的访问。

例如,下面的函数初始化一个 value count,然后返回一个嵌套函数的函数句柄increment

function fHandle = start_counting(count)

  disp(count);
  fHandle = @increment;

  function increment
    count = count+1;
    disp(count);
  end

end

由于函数increment是一个嵌套函数,它只能在函数内部使用start_counting(即工作空间start_counting是它的“作用域”)。但是,通过返回函数的句柄increment,我仍然可以在外部使用它start_counting,并且它仍然保留对start_counting!工作区中变量的访问权限。这允许我这样做:

>> fh = start_counting(3);  % Initialize count to 3 and return handle
     3

>> fh();  % Invoke increment function using its handle
     4

>> fh();
     5

请注意,即使我们在函数之外,我们如何保持递增计数start_countingstart_counting但是您可以通过使用不同的数字再次调用并将函数句柄存储在另一个变量中来做一些更有趣的事情:

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

请注意,这两个不同的计数器独立运行。该函数处理fhfh2指向函数的不同实例,其中不同的increment工作空间包含count.

除了上述之外,将函数句柄与嵌套函数结合使用还可以帮助简化 GUI 设计,正如我在另一篇 SO 帖子中所说明的那样。

于 2009-04-28T13:44:21.950 回答
18

函数句柄是matlab中一个非常强大的工具。一个好的开始是阅读在线帮助,它会给你比我所能提供的更多的东西。在命令提示符下,键入

doc function_handle

函数句柄是一种在一行中创建函数的简单方法。例如,假设我希望对函数 sin(k*x) 进行数值积分,其中 k 具有一些固定的外部值。我可以使用内联函数,但函数句柄要整洁得多。定义一个函数

k = 2;
fofx = @(x) sin(x*k);

看到我现在可以在命令行评估函数 fofx 了。MATLAB 知道 k 是什么,所以我们现在可以将 fofx 用作函数。

fofx(0.3)
ans =
         0.564642473395035

事实上,我们可以传递 fofx,有效地作为一个变量。例如,让我们调用 quad 来进行数值积分。我将选择区间 [0,pi/2]。

quad(fofx,0,pi/2)
ans =
         0.999999998199215

如您所见,quad 进行了数值积分。(顺便说一句,内联函数至少会慢一个数量级,而且更不容易使用。)

x = linspace(0,pi,1000);
tic,y = fofx(x);toc
Elapsed time is 0.000493 seconds.

作为比较,尝试一个内联函数。

finline = inline('sin(x*k)','x','k');
tic,y = finline(x,2);toc
Elapsed time is 0.002546 seconds.

函数句柄的一个巧妙之处在于您可以动态定义它。在区间 [0,2*pi] 上最小化函数 cos(x)?

xmin = fminbnd(@(x) cos(x),0,2*pi)
xmin =
          3.14159265358979

MATLAB 中的函数句柄还有很多其他用途。我在这里只触及了表面。

于 2009-04-28T11:41:10.187 回答
15

免责声明:代码未经测试...

函数句柄运算符允许您创建对函数的引用并像任何其他变量一样传递它:

% function to add two numbers
function total = add(first, second) 
    total = first + second;
end

% this variable now points to the add function
operation = @add;

一旦你有了一个函数句柄,你就可以像普通函数一样调用它:

operation(10, 20); % returns 30

函数句柄的一个好处是您可以像传递任何其他数据一样传递它们,因此您可以编写作用于其他函数的函数。这通常使您可以轻松地分离出业务逻辑:

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

Matlab 文档对Matlab 语法有更完整的描述,并描述了函数句柄的一些其他用途,如图形回调。

于 2009-04-28T11:15:02.217 回答