38

@(関数ハンドル) 演算子の意味と、それを使用する理由を説明してもらえますか?

4

3 に答える 3

50

MATLABの関数ハンドル演算子は、本質的に関数の特定のインスタンスへのポインターのように機能します。他のいくつかの回答では、その用途のいくつかについて説明していますが、ここで、「スコープ内」ではなくなった関数へのアクセスを維持するという、よくある別の用途を追加します。

たとえば、次の関数は値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

function の外にいても、どのように count をインクリメントし続けることができるかに注目してください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

これら 2 つの異なるカウンターは独立して動作することに注意してください。関数は、 の一意の値を含むさまざまなワークスペースを持つ関数のさまざまなインスタンスを処理fhおよびポイントします。fh2incrementcount

上記に加えて、ネストされた関数と組み合わせて関数ハンドルを使用すると、GUI 設計を合理化するのにも役立ちます

于 2009-04-28T13:44:21.950 に答える
18

関数ハンドルは、matlab の非常に強力なツールです。まずは、オンライン ヘルプを読むことから始めるとよいでしょう。コマンド プロンプトで次のように入力します。

doc function_handle

関数ハンドルは、1 行で関数を作成する簡単な方法です。たとえば、関数 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 は数値積分を行いました。(ちなみに、インライン関数は少なくとも 1 桁は遅くなり、操作もはるかに簡単ではなくなります。)

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

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.

于 2009-04-28T11:15:02.217 に答える