Spec-Zone.ru › Octave 9

Далее: Перегрузка и автозагрузка, Предыдущее: Приватные функции, Вверх: Файлы функций [Оглавление][Индекс]

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 в сочетании с вложенными функциями лучше избегать.

Как и в случае с подфункциями, только первая вложенная функция в файле может быть вызвана извне. Внутри функции правила более сложные. В целом, вложенная функция может вызывать:

  1. Глобально видимые функции
  2. Любую функцию, которую может вызвать родитель вложенной функции
  3. Функции-сверстники (функции с одинаковыми родителями)
  4. Прямых потомков

В качестве сложного примера рассмотрим родительскую функцию 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–2023 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.2.0/Nested-Functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API