Когда я учился в бакалавриате по EE, MATLAB требовал, чтобы каждая функция была определена в отдельном файле, даже если она была лайнер.
Сейчас я учусь в аспирантуре, и мне нужно написать проект в MATLAB. Требуется ли это для более новых версий MATLAB?
Если в файл можно поместить более одной функции, Есть ли какие-либо ограничения к этому? Например, можно ли получить доступ ко всем функциям в файле из-за пределов файла или только к функции, имя которой совпадает с именем файла?
Примечание. Я использую версию MATLAB R2007b.
Первая функция в m-файле (то есть основная функция) вызывается при вызове этого m-файла. Не требуется, чтобы основная функция имела то же имя, что и m-файл, но для ясности оно должно. Когда функция и имя файла различаются, для вызова основной функции необходимо использовать имя файла.
Все последующие функции в m-файле, называемые локальными функциями (или «подфункциями» в старой терминологии), могут вызываться только основной функцией и другими локальными функциями в этом m-файле. Функции в других m-файлах не могут их вызывать. Начиная с R2016b, вы также можете добавлять локальные функции в скрипты, хотя поведение области остается прежним (то есть их можно вызывать только из скрипта).
Кроме того, вы также можете объявлять функции внутри других функций. Они называются вложенными функциями, и их можно вызывать только из функции, в которую они вложены. Они также могут иметь доступ к переменным в функциях, в которые они вложены, что делает их весьма полезными, хотя и немного сложными в работе.
Еще пища для размышлений...
Есть несколько способов обойти описанное выше нормальное поведение области видимости функции, например, передать дескрипторы функций в качестве выходных аргументов, как указано в ответах SCFrench и Джонаса. ] (что, начиная с R2013b, облегчается функцией localfunctions
). Однако я бы не советовал заводить привычку прибегать к таким уловкам, так как, вероятно, есть гораздо лучшие варианты организации ваших функций и файлов.
Например, предположим, что у вас есть основная функция A
в m-файле Am
вместе с локальными функциями D
, E
и F
. Теперь предположим, что у вас есть две другие связанные функции B
и C
в m-файлах Bm
и Cm
соответственно, которые вы также хотите чтобы иметь возможность вызывать D
, E
и F
. Вот несколько вариантов, которые у вас есть:
Поместите D
, E
и F
в свои отдельные m-файлы, чтобы любая другая функция могла вызывать их. Недостатком является то, что объем этих функций велик и не ограничивается только A
, B
и C
, но преимущество в том, что это довольно просто.
Создайте m-файл defineMyFunctions
(как в примере Йонаса) с D
, E
и F
в качестве локальных функций. и основная функция, которая просто возвращает им дескрипторы функций.Это позволяет вам хранить D
, E
и F
в одном и том же файле, но ничего не делает в отношении объема этих функций, поскольку любая функция которые могут вызывать defineMyFunctions
, могут вызывать их. Затем вам также придется беспокоиться о передаче дескрипторов функций в качестве аргументов, чтобы убедиться, что они у вас есть там, где они вам нужны.
Скопируйте D
, E
и F
в B.m
и C.m
как локальные функции. Это ограничивает область их использования только A
, B
и C
, но делает обновление и обслуживание вашего кода кошмаром, потому что у вас есть три копии один и тот же код в разных местах.
Используйте приватные функции! Если у вас есть A
, B
и C
в одном каталоге, вы можете создать подкаталог с именем private
и поместить D
, E
и F
там, каждый как отдельный m-файл. Это ограничивает их область действия, поэтому они могут вызываться только функциями из каталога непосредственно выше (например, A
, B
и C
) и удерживает их вместе в каталоге. то же место (но все еще разные m-файлы):
myDirectory/
Являюсь
Б.м.
См
частный/
Д.м.
Эм
Ф.м
Все это несколько выходит за рамки вашего вопроса и, вероятно, содержит больше деталей, чем вам нужно, но я подумал, что было бы неплохо коснуться более общей проблемы организации всех ваших m-файлов. ;)
Единственный способ иметь несколько отдельно доступных функций в одном файле — определить СТАТИЧЕСКИЕ МЕТОДЫ с использованием объектно-ориентированного программирования. Вы бы получили доступ к функции как myClass.static1()
, myClass.static2()
и т. д.
Функциональность ООП официально поддерживается только с R2008a, поэтому, если вы не хотите использовать старый, недокументированный синтаксис ООП, ответ для вас - нет, как объяснил @gnovice.
EDIT
Еще один способ определить внутри файла несколько функций, доступных извне, — создать функцию, которая возвращает несколько дескрипторов функций. Другими словами, вы бы назвали определяющую функцию как [fun1,fun2,fun3]=defineMyFunctions
, после чего вы могли бы использовать out1=fun1(inputs)
и т. д.
Как правило, ответ на ваш вопрос - нет, вы не можете определить более одной видимой извне функции в файле. Однако вы можете возвращать дескрипторы функций локальным функциям, и удобный способ сделать это — сделать их полями структуры. Вот пример:
function funs = makefuns
funs.fun1=@fun1;
funs.fun2=@fun2;
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
А вот как это можно использовать:
>> myfuns = makefuns;
>> myfuns.fun1(5)
ans =
5
>> myfuns.fun2()
ans =
1