11.10.4 Nested Functions

Last-modified: 2025-03-13 (木) 22:11:03

11.10.4 ネストされた関数

ネストされた関数は、メイン関数のみがファイル外から参照できるという点でサブ関数に似ています。ただし、子関数が親関数内のローカル変数にアクセスすることもできます。この共有アクセスは、グローバル変数を使用して情報を共有するのと似ていますが、グローバル変数は Octave の残りの部分からは参照できません。プログラミング戦略として、このようにデータを共有すると、保守が困難なコードが作成されることがあります。可能な場合は、ネストされた関数の代わりにサブ関数を使用することをお勧めします。

簡単な例として、共有変数xfooを使用してネストされた子関数 を呼び出す親関数 を考えてみましょう。 bar

function y = foo ()
 x = 10;
 bar ();
 y = x;
 function bar ()
   x = 20;
 endfunction
endfunction
foo ()
⇒ 20

x を共有するための特別な構文がないことに注意してください。これにより、親関数とその子の間で誤って変数が共有されるという問題が発生する可能性があります。通常、変数は継承されますが、子関数のパラメーターと戻り値は子関数に対してローカルです。

foobarここで、変数xと y を使用する関数を考えます。 は、 x をパラメーターとして受け取り 、 yfoobarを返すネストされた関数を呼び出します。 次に、 何らかの計算を行う foofoobatを呼び出します。

function z = foobar ()
 x = 0;
 y = 0;
 z = foo (5);
 z += x + y;
 function y = foo (x)
   y = x + bat ();
   function z = bat ()
     z = x;
   endfunction
 endfunction
endfunction
foobar ()
   ⇒ 10

のxとyは、それぞれ戻り値とパラメータ foobarであるため、ゼロのままであることに注意することが重要です。のxは、 のxを参照します。 foobatfoo

変数の継承は、およびスクリプトに問題を引き起こします。親関数で新しい変数が作成された場合、ネストされた子関数で何が起こるかは明確ではありません。たとえば、ネストされた子関数を持つeval親関数を考えてみましょう 。 foobar

function y = foo (to_eval)
 bar ();
 eval (to_eval);
 function bar ()
   eval ("x = 100;");
   eval ("y = x;");
 endfunction
endfunction
foo ("x = 5;")
   ⇒ error: can not add variable "x" to a static workspace
foo ("y = 10;")
   ⇒ 10
foo ("")
   ⇒ 100

親関数はfoo新しい変数 xを作成できませんが、子関数はbar成功しました。さらに、evalステートメント内でも、のyは親関数のybarと同じです。ネストされた関数と組み合わせて を使用することは避けるのが最善です。 fooeval

サブ関数と同様に、ファイル内の最初のネストされた関数のみが外部から呼び出すことができます。関数内ではルールがより複雑になります。一般に、ネストされた関数は以下を呼び出すことができます。

グローバルに表示される機能
ネストされた関数の親が呼び出せる関数
兄弟関数(同じ親を持つ関数)
直系の子供
複雑な例として、とex_topの 2 つの子関数を持つ親関数を考えます。さらに、にはさらに 2 つの子関数、と があります。例: ex_aex_bex_aex_aaex_ab

function ex_top ()
 ## Can call: ex_top, ex_a, and ex_b
 ## Can NOT call: ex_aa and ex_ab
 function ex_a ()
   ## Can call everything
   function ex_aa ()
     ## Can call everything
   endfunction
   function ex_ab ()
     ## Can call everything
   endfunction
 endfunction
 function ex_b ()
   ## Can call: ex_top, ex_a, and ex_b
   ## Can NOT call: ex_aa and ex_ab
 endfunction
endfunction