Вложенные функции

Этот пример показывает, как использовать вложенные функции, чтобы легко осуществлять обмен данными, а также для создания индивидуально настраиваемых функций.

Пример 1: Обмен данными

Давайте сначала смотреть на taxDemo.m, который содержит вложенную функцию.

type taxDemo.m
function y = taxDemo(income)
%TAXDEMO Used by NESTEDDEMO.
% Calculate the tax on income.

% Copyright 1984-2014 The MathWorks, Inc.

AdjustedIncome = income - 6000; % Calculate adjusted income

% Call 'computeTax' without passing 'AdjustedIncome' as a parameter.

y = computeTax;

   function y = computeTax
      
      % This function can see the variable 'AdjustedIncome'
      % in the calling function's workspace
      y = 0.28 * AdjustedIncome;
   end
end

Вложенная функция computeTax видит переменные в рабочей области родительской функции. Это делает совместное использование данных между несколькими вложенными функциями легким и особенно полезным при обработке больших наборов данных. Мы можем вызвать функцию обычным способом.

y = taxDemo(80e3) % What is the tax on $80k income?
y = 2.0720e+04

Для вложенных функций оператор end требуется в конце функции. Можно также вложить функции к любому уровню.

Пример 2: Создание индивидуально настраиваемых функций

Вложенные функции позволяют способности создать настроенные функции. Давайте посмотрим на makefcn.m, который содержит вложенную функцию.

type makefcn.m
function fcn = makefcn(a,b,c)
%MAKEFCN Used by NESTEDDEMO.
% This function returns a handle to a customized version of 'parabola'.
% a,b,c specifies the coefficients of the function.

% Copyright 1984-2014 The MathWorks, Inc.

fcn = @parabola;   % Return handle to nested function

   function y = parabola(x)
      % This nested function can see the variables 'a','b', and 'c'
      y = a*x.^2 + b.*x + c;
   end
end

Когда вы вызываете makefcn, он возвращает указатель на функцию в индивидуально настраиваемую функцию. Например:

f = makefcn(3,2,10);
g = makefcn(0,5,25);

f и g являются указателями на две функции, каждого с различными коэффициентами. Мы можем выполнить функции при помощи их указателей на функцию и передающий в параметрах.

y = f(2)
y = 26
y = g(2)
y = 35

Мы можем также передать указатель на функциональные функции, такие как оптимизация или интегрирование.

minimum = fminbnd(f,-5,5);

Или постройте функцию в области значений.

fplot(f, [-6 6], 'b-')                  % Plot f over a range of x
hold on;
plot(2,f(2),'bd');                      % Plot a marker at (2,f(2))
plot(minimum,f(minimum),'bs');          % Plot at minimum of f
text(minimum,f(minimum)-2,'Minimum');
fplot(g, [-6 6], 'r-')
plot(2,g(2),'rd');                      % Plot a marker at (2,g(2))
ylim([-10 60])
hold off;

Пример 3: Создание индивидуально настраиваемых функций с состоянием

Давайте посмотрим на makecounter.m, который содержит вложенную функцию.

type makecounter.m
function countfcn = makecounter(initvalue)
%MAKECOUNTER Used by NESTEDDEMO.
% This function returns a handle to a customized nested function 'getCounter'.
% initvalue specifies the initial value of the counter whose's handle is returned.

% Copyright 1984-2014 The MathWorks, Inc.

currentCount = initvalue; % Initial value
countfcn = @getCounter;   % Return handle to getCounter

   function count = getCounter
      % This function increments the variable 'currentCount', when it
      % gets called (using its function handle) .
      currentCount = currentCount + 1;
      count = currentCount;
   end
end

Когда вы вызываете makecounter, он возвращает указатель на свою вложенную функцию getCounter. getCounter настраивается значением initvalue, переменная, которую это видит через вложение в рабочей области makecounter.

counter1 = makecounter(0);  % Define counter initialized to 0
counter2 = makecounter(10); % Define counter initialized to 10

Здесь мы создали два индивидуально настраиваемых счетчика: тот, который запускается в 0 и тот, который запускается в 10. Каждый указатель является отдельным экземпляром функции и ее рабочей области вызова. Теперь мы можем вызвать внутреннюю вложенную функцию через ее указатель. counter1 не берет параметры, но он мог.

counter1Value = counter1()
counter1Value = 1

Мы можем вызвать эти две функции независимо, когда существует две отдельных рабочих области для родительских сохраненных функций. Они остаются в памяти, в то время как указатели на их вложенные функции существуют. В этом случае переменная currentCount обновляется, когда counter1 называется.

counter1Value = counter1()
counter1Value = 2
counter2Value = counter2()
counter2Value = 11