11.10.4 Вложенные функции
Вложенные функции похожи на подфункции тем, что за пределами файла видна только главная функция. Однако они также позволяют дочерним функциям обращаться к локальным переменным родительской функции. Такой совместный доступ напоминает использование глобальной переменной для обмена информацией — но эта глобальная переменная не видна остальной части Octave. Использование такого способа обмена данными в качестве стратегии программирования может привести к созданию кода, который трудно сопровождать. По возможности рекомендуется использовать подфункции вместо вложенных функций.
В качестве простого примера рассмотрим родительскую функцию foo, которая вызывает вложенную дочернюю функцию bar с общей переменной x.
function y = foo ()
x = 10;
bar ();
y = x;
function bar ()
x = 20;
endfunction
endfunction
foo ()
⇒ 20 Обратите внимание, что для совместного использования x не требуется специальный синтаксис. Это может привести к проблемам из-за случайного совместного использования переменных родительской функцией и её дочерней функцией. Хотя переменные обычно наследуются, параметры и возвращаемые значения дочерней функции являются локальными для неё.
Теперь рассмотрим функцию foobar, использующую переменные x и y. foobar вызывает вложенную функцию foo, которая принимает x в качестве параметра и возвращает y. Затем foo вызывает bat, которая выполняет некоторые вычисления.
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 остаются равными нулю, поскольку в foo они являются возвращаемым значением и параметром соответственно. x в bat относится к x в foo.
Наследование переменных создаёт проблему для eval и скриптов. Если в родительской функции создаётся новая переменная, неясно, что должно происходить во вложенных дочерних функциях. Например, рассмотрим родительскую функцию foo с вложенной дочерней функцией bar:
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 в bar — это та же переменная y, что и в родительской функции foo. Использования eval в сочетании с вложенными функциями лучше избегать.
Как и в случае с подфункциями, извне можно вызвать только первую вложенную функцию в файле. Внутри функции правила сложнее. В общем случае вложенная функция может вызывать:
- Глобально видимые функции
- Любые функции, которые может вызывать родительская функция вложенной функции
- Функции-соседи (функции с одинаковыми родительскими функциями)
- Непосредственные дочерние функции
В качестве более сложного примера рассмотрим родительскую функцию ex_top с двумя дочерними функциями, ex_a и ex_b. Кроме того, у ex_a есть ещё две дочерние функции, ex_aa и ex_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
© 1996–2026 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v9.4.0/Nested-Functions.html