2009-04-28 19 views

答えて

47

MATLABのfunction handle operatorは、本質的に関数の特定のインスタンスへのポインタのように機能します。他の答えのいくつかは、その使用法のいくつかについて議論してきましたが、ここではもう私がそれを持っていることをもう1つ追加します。これは、もはや "スコープ内"ではない関数へのアクセスを維持することです。以下の関数は値countを初期化し、その後、ネストされた関数incrementに関数ハンドルを返し

例えば、:関数incrementnested functionあるので

function fHandle = start_counting(count) 

    disp(count); 
    fHandle = @increment; 

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

end 

、それは関数内でのみ使用することができますstart_counting(つまり、start_countingの作業領域がその「範囲」です)。しかし、関数incrementへのハンドルを返すことで、私はまだstart_countingの外でそれを使用することができ、それでも、作業領域の変数へのアクセスは、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 

注意してください。これら二つの異なるカウンタが独立して動作することを

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

お知らせ:しかし、あなたはさらに興味深い異なる番号で再びstart_countingを呼び出し、別の変数に関数ハンドルを格納することで何かを行うことができます。 fhfh2は、異なるワークスペースを持つincrementの異なるインスタンスを指し、countの一意の値を含んでいます。

さらに、ネストされた関数と組み合わせて関数ハンドルを使用すると、this other SO postで示すように、GUI設計を合理化するのに役立ちます。

+2

重要なことは、functionキーワードで作成された関数と@演算子で作成された関数が異なるスコープ規則を持つことです。 hGetCount = @ getCount;関数c = getCount; c =カウント;終わり;上記で説明したように、評価時に(レキシカルスコープを使用して)count変数の検索を行います。関数hGetCount = @()count;作成時にcount変数の値が代入されます。 –

+2

関数ハンドルを使用すると、メイン関数の外部からネストされた関数またはサブ関数を操作できます。 GUIプログラミングのお手伝いができます。 –

+0

@ Mr. Fooz:良い点! @演算子で作成された匿名関数は、作成時にワークスペースに存在する変数の値を単に代入するだけで、「通常の」関数は変数を格納するための独自の作業領域を持ちます。 – gnovice

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 

一つの良いところは、ハンドルあなただけの任意のOTHのように周りにそれらを渡すことができるということです他の関数に作用する関数を記述することができます。これは、多くの場合、あなたは簡単にビジネスロジックを分離することができます:

% 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 documentationは、MATLAB構文のより完全な説明があり、機能は、グラフィックスコールバックのように扱うためのいくつかの他の用途について説明します。

17

関数ハンドルは、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 quadを呼び出します。区間[0、π/ 2]を選択します。

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

ご覧のとおり、クワッドは数値積分を行いました。 (ちなみに、インライン関数が遅く、およびで動作するようにはるかに簡単magitudeの少なくとも順だったでしょう。)

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の関数ハンドルには、他にも多くの用途があります。私はここで表面を傷つけただけです。

関連する問題