このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
入れ子関数
入れ子関数とは
入れ子関数は、親関数内に完全に含まれている関数です。プログラム ファイル内の関数は、入れ子関数を含むことができます。
たとえば、parent
という以下の関数は、nestedfx
という入れ子関数を含んでいます。
function parent disp('This is the parent function') nestedfx function nestedfx disp('This is the nested function') end end
入れ子関数と他の種類の関数の主な違いは、入れ子関数は自身の親関数で定義された変数にアクセスして変更できるということです。その結果、
入れ子関数は、入力引数として明示的に渡されていない変数を使用できます。
親関数で、入れ子関数の実行に必要なデータをもつ入れ子関数のハンドルを作成できます。
入れ子関数の必要条件
通常、関数には
end
ステートメントは不要です。ただし、プログラム ファイルで関数を入れ子にするには、そのファイル内の "すべての" 関数でend
ステートメントを使用しなければなりません。if/elseif/else
、switch/case
、for
、while
、try/catch
など、MATLAB® の任意のプログラム コントロール ステートメント内で、 入れ子関数を定義することはできません。入れ子関数は (
feval
を使用せずに) 名前で直接呼び出すか、または (str2func
ではなく)@
演算子を使って作成した関数ハンドルで呼び出さなければなりません。入れ子関数またはそれを含む関数内の変数は、すべて明示的に定義しなければなりません。したがって、変数に値を代入する関数やスクリプトを呼び出すには、関数ワークスペースにその変数が既に存在していなければなりません。(詳細は、エラーの解決: 静的なワークスペースへの変数追加の試みを参照)
親関数と入れ子関数間での変数の共有
一般に、ある関数ワークスペース内の変数を別の関数で使用することはできません。ただし、入れ子関数は、自身を含む関数のワークスペースにある変数にアクセスして変更することができます。
つまり、入れ子関数と親関数の双方は、同じ変数を引数として渡すことなく変更できます。たとえば、関数 main1
および main2
のそれぞれでは、メイン関数と入れ子関数ともに変数 x
にアクセスできます。
function main1 x = 5; nestfun1 function nestfun1 x = x + 1; end end | function main2 nestfun2 function nestfun2 x = 5; end x = x + 1; end |
所定の変数が親関数で使用されない場合は、入れ子関数のローカル変数として扱われます。たとえば次の関数 main
では、2 つの入れ子関数にそれぞれ独自バージョンの x
があり、その相互対話は不可能です。
function main nestedfun1 nestedfun2 function nestedfun1 x = 1; end function nestedfun2 x = 2; end end
出力引数を返す関数は、ワークスペースに出力用の変数をもっています。ただし、親関数は、入れ子関数の出力変数を明示的に要求した場合のみ、その出力変数をもちます。たとえば、この関数 parentfun
は、ワークスペースに変数 y
を "もちません"。
function parentfun x = 5; nestfun; function y = nestfun y = x + 1; end end
コードを以下のように変更すると、変数 z
は parentfun
のワークスペースに入るようにます。
function parentfun x = 5; z = nestfun; function y = nestfun y = x + 1; end end
ハンドルを使用した関数パラメーターの格納
入れ子関数は 3 つのソースから変数を使用できます。
入力引数
その入れ子関数内で定義された変数
親関数で定義された変数。"スコープ外の" 変数とも呼ばれます。
入れ子関数の関数ハンドルを作成する場合、そのハンドルはその関数名のほかに、スコープ外の変数の値も格納します。
たとえば、makeParabola.m
というファイルに新しい関数を作成します。この関数はいくつかの多項式係数を受け取り、その多項式の値を計算する入れ子関数のハンドルを返します。
function p = makeParabola(a,b,c) p = @parabola; function y = parabola(x) y = a*x.^2 + b*x + c; end end
関数 makeParabola
は、係数 a
、b
および c
の値を含む関数 parabola
のハンドルを返します。
コマンド ラインで、係数値 1.3
、.2
および 30
を指定して関数 makeParabola
を呼び出します。返された関数ハンドル p
を使用して特定の点で多項式を評価します。
p = makeParabola(1.3,.2,30); X = 25; Y = p(X)
Y = 847.5000
多くの MATLAB 関数は関数ハンドル入力を受け取って値の範囲で関数を評価します。たとえば、放物型方程式を -25
~ +25
の範囲でプロットします。
fplot(p,[-25,25])
さまざまな多項式係数を使用する複数の関数 parabola
のハンドルを作成できます。
firstp = makeParabola(0.8,1.6,32); secondp = makeParabola(3,4,50); range = [-25,25]; figure hold on fplot(firstp,range) fplot(secondp,range,'r:') hold off
入れ子関数の可視性
それぞれの関数には、一定の "スコープ" があります。スコープとは、その関数から見える一連の他の関数です。入れ子関数は、以下の方法で使用できます。
入れ子関数の 1 つ上のレベルから呼び出す (次のコードでは、関数
A
はB
またはD
は呼び出せますが、C
とE
は呼び出せません)。同じ親関数内にある同じレベルの入れ子関数から呼び出す (関数
B
はD
を、そしてD
はB
を呼び出せます)。下位レベルの関数から呼び出す (関数
C
はB
またはD
を呼び出せますが、E
は呼び出せません)。function A(x, y) % Main function B(x,y) D(y) function B(x,y) % Nested in A C(x) D(y) function C(x) % Nested in B D(x) end end function D(x) % Nested in A E(x) function E(x) % Nested in D disp(x) end end end
入れ子関数のスコープを拡張する最も簡単な方法は、ハンドルを使用した関数パラメーターの格納で説明されているように、関数ハンドルを作成してそれを出力引数として返すことです。入れ子関数を呼び出すことができる関数のみが、入れ子関数へのハンドルを作成できます。