誰かが@
(関数ハンドル)演算子の意味とそれを使用する理由を説明できますか?
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
関数start_counting
の外にいる場合でも、カウントをインクリメントし続ける方法に注意してください。しかし、start_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
およびfh2
ポイントを処理し、increment
の一意の値を含むさまざまなワークスペースで関数count
の異なるインスタンスをポイントします。
上記に加えて、ネストされた関数と組み合わせて関数ハンドルを使用すると、 this other SO post 。
関数ハンドルは、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の関数ハンドルには、他にも多くの用途があります。ここで表面をひっかいただけです。
免責事項:コードはテストされていません...
関数ハンドル演算子を使用すると、関数への参照を作成し、他の変数と同じように渡すことができます。
% 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
関数ハンドルの良い点の1つは、他のデータと同じように渡すことができるため、他の関数に作用する関数を作成できることです。これにより、多くの場合、ビジネスロジックを簡単に分離できます。
% 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構文の詳細な説明があり、グラフィックスコールバックなどの関数ハンドルのその他の使用法について説明しています。