Функции: файлы-функции и анонимные @
Как оформить переиспользуемый код: от файла-функции с несколькими выходами до однострочной анонимной функции.
Функция в MATLAB имеет собственную область видимости и может возвращать несколько значений сразу.
Объявление функции
Функция начинается со слова function, перечня выходов в квадратных скобках, имени и входов. В отличие от скрипта, переменные функции локальны — они не попадают в рабочую область. Несколько выходов — характерная черта MATLAB: вы видели это у max и size.
function [s, p] = sum_prod(a, b)
s = a + b; % первый выход
p = a * b; % второй выход
end
% вызов:
[su, pr] = sum_prod(3, 4); % su = 7, pr = 12
Файл-функция традиционно сохраняется как sum_prod.m — имя файла должно совпадать с именем функции. С версии R2016b функции можно писать и в конце скрипта.
Анонимные функции через @
Для коротких выражений не нужен отдельный файл — есть анонимные функции. Символ @ создаёт функцию «на лету»: @(x) x.^2 + 1. Их хранят в переменных и передают другим функциям. Анонимная функция «захватывает» значения переменных в момент создания.
f = @(x) x.^2 + 1;
f(3) % 10
g = @(x, y) x + y;
g(2, 5) % 7
Вывод:
ans =
10
ans =
7
Функции как аргументы
Анонимные функции — основной способ передать «что вычислять» в численные методы. Когда вы решаете уравнение или интегрируете, вы передаёте саму функцию через @. Это пригодится в разделе про численные методы, где ode45 и integral принимают функцию-аргумент.
% площадь под x^2 от 0 до 1 будет считаться так:
fun = @(x) x.^2;
% integral(fun, 0, 1) → около 0.3333
Как работает под капотом
Анонимная функция при создании делает снимок переменных, которые в ней упомянуты, но не являются аргументами. Если потом изменить исходную переменную, функция всё равно будет использовать старое значение. Это удивляет тех, кто ждёт «живой» ссылки. Например, если задать a=2; h=@(x) a*x;, а затем a=10, вызов h(3) всё равно даст 6, а не 30 — внутри функции a «заморожено» как 2.
Частые ошибки
- Назвать файл иначе, чем функцию, — MATLAB вызовет функцию по имени файла, а не по объявлению.
- Забыть точку в
x.^2внутри анонимной функции — тогда она не сработает для векторного аргумента. - Ждать, что анонимная функция увидит более позднее изменение захваченной переменной.
Локальная область видимости как защита
Главное преимущество функции перед скриптом — изоляция. Переменные внутри функции существуют только на время её работы и не «протекают» в рабочую область. Это кажется ограничением, но на деле спасает от целого класса ошибок: в большом скрипте переменные легко перезаписать по неосторожности, тогда как функция гарантирует, что её внутренняя кухня никого не затронет. Данные входят через аргументы, выходят через возвращаемые значения — и больше никак. Эта дисциплина делает код предсказуемым: чтобы понять функцию, достаточно посмотреть на её вход и выход, не держа в голове всё состояние программы.
Функции высшего порядка
Поскольку функцию можно передать в другую функцию через @ (создав дескриптор функции, function handle), MATLAB поддерживает функции высшего порядка. Численные методы этим и живут: integral(@f, a, b), fzero(@f, x0), ode45(@f, ...) — все принимают вычисляемую функцию как аргумент. Дескриптор именованной функции пишут как @myfunc, а короткое выражение — анонимной функцией @(x) .... Этот механизм превращает «что вычислять» в обычное передаваемое значение и лежит в основе всего раздела численных методов. Без него пришлось бы зашивать формулу внутрь каждого решателя; с ним один универсальный решатель работает с любой вашей функцией.
Итоги
function [out1,out2] = name(in)— несколько выходов, локальная область.@(x) выражение— анонимная функция для коротких формул.- Анонимная функция замораживает захваченные переменные в момент создания.