Начиная с R2019b, MATLAB изменяет правила разрешения имен, влияя на порядок приоритета переменных, вложенных функций, локальных функций и внешних функций. Новые правила упрощают и стандартизируют разрешение имен. Дополнительные сведения см. в разделе Порядок очередности функций.
Эти изменения влияют на поведение import функция. Необходимо проанализировать и, возможно, обновить код. Чтобы начать, выполните поиск инструкций импорта в коде. Например, используйте команду «Найти файлы и папки» для поиска .m и .mlx файлы, содержащие текст import. Эти результаты поиска можно найти при оценке последствий следующих изменений.
Начиная с R2019b, ошибка возникает при использовании идентификатора сначала в качестве локальной или импортированной функции, а затем в качестве переменной. В предыдущих версиях идентификатор может использоваться для различных целей в области действия функции, что приводит к неоднозначному коду.
Если это изменение влияет на код, переименуйте переменную или функцию так, чтобы они имели разные имена.
| Начиная с R2019b | Обновленный код | R2019a и более ранние |
|---|---|---|
Имя function myfunc % local is an undefined variable local(1); % Errors local = 2; disp(local); end function local(x) disp(x) end | Переименование функции function myfunc localFcn(1); local = 2; disp(local); end function localFcn(x) disp(x) end | Этот код отображается function myfunc local(1); % local is a function local = 2; disp(local); end function local(x) disp(x) end |
Начиная с R2019b, MATLAB ® не использует операторы индексирования для идентификации переменных в программе. Ранее идентификатор без явного объявления рассматривался как переменная при индексировании двоеточием ,endили фигурные скобки. Например, x был обработан как переменная в x(a,b,:), x(end), и x{a}.
Рассмотрим следующий код. MATLAB используется для лечения x как переменная из-за индексации двоеточием. Начиная с R2019b, если на пути существует функция с тем же именем, MATLAB обрабатывает x как функция.
function myfunc load data.mat; % data.mat contains variable x disp(x(:)) end
Если вы намерены использовать x как переменная из data.mat вместо функции явным образом объявите ее. Аналогично, для использования идентификатора x в качестве переменной, полученной из сценария, объявите ее перед вызовом сценария. Это новое поведение также применяется, если переменная неявно введена функциями sim, eval, evalc, и assignin.
В этой таблице приведены примеры обновления кода.
| Прежде | После |
|---|---|
function myfunc load data.mat; disp(x(:)) end | function myfunc load data.mat x; disp(x(:)) end |
function myfunc2 myscript; % Contains variable x disp(x(:)) end | function myfunc2 x = []; myscript; disp(x(:)) end |
Начиная с R2019b, совместное использование идентификатора в качестве переменной между вложенной функцией и ее родительской функцией возможно только в том случае, если идентификатор явно объявлен в качестве переменной в родительской функции.
Например, в следующем коде идентификатор x в myfunc отличается от переменной x во вложенной функции. Если x - функция на тракте, обрабатываемая MATLAB x в myfunc как функция, и код запускается. В противном случае MATLAB выдает ошибку.
function myfunc nested; x(3) % x is not a shared variable function nested x = [1 2 3]; end end
В предыдущих версиях, если x была функцией на пути, MATLAB рассматривал ее как функцию в myfunc и в качестве переменной в nested. Если x не был функцией на пути, MATLAB рассматривал его как переменную, совместно используемую myfunc и nested. Это привело к появлению кода, выход которого зависел от состояния пути.
Чтобы использовать идентификатор в качестве переменной, совместно используемой родительскими и вложенными функциями, может потребоваться обновить код. Например, можно инициализировать идентификатор для пустого массива в родительской функции.
| Прежде | После |
|---|---|
function myfunc nested; x(3) function nested x = [1 2 3]; end end | function myfunc x = []; nested; x(3) function nested x = [1 2 3]; end end |
Начиная с R2019b импортированные функции из импорта на основе подстановочных знаков имеют более низкий приоритет, чем переменные, вложенные функции и локальные функции. В R2019a и более ранних версиях импортирует в функции затененные локальные функции и вложенные функции.
Например, в этом коде оператор local() требования myfunc/local вместо pkg1.local в импорте на основе подстановочных знаков. Заявление nest() требования myfunc/nest вместо pkg1.nest.
| Начиная с R2019b | R2019a и более ранние |
|---|---|
function myfunc % Import includes functions local and nest import pkg1.* local() % Calls myfunc/local function nest end nest(); % Calls myfunc/nest end function local end |
function myfunc % Import includes functions local and nest import pkg1.* local() % Calls pkg1.local and % displays warning since R2018a function nest end nest(); % Calls pkg1.nest end function local end |
В результатах поиска для import, найдите операторы, содержащие подстановочный символ (*).
Начиная с R2019b, полный импорт с общим именем вложенной функции в той же области приводит к ошибке.
| Начиная с R2019b | Обновленный код | R2019a и более ранние |
|---|---|---|
Эта функция ошибается, так как совместно использует имя с вложенной функцией в той же области. function myfunc import pkg.nest % Errors nest(); function nest end end | Вызов функции function myfunc import pkg.nest nest(); function newNest end end | Эта функция вызывает функцию function myfunc import pkg.nest nest(); % Calls pkg.nest function nest end end |
Ошибка этой функции из-за объявления переменной с тем же именем, что и импортированная функция function myvarfunc import pkg.nest % Errors nest = 1 end | Переименовать переменную function myvarfunc import pkg.nest % Errors thisNest = 1 end | Эта функция изменяет переменную function myvarfunc import pkg.nest nest = 1 % Modifies variable nest and % displays warning since R2018a end |
Начиная с R2019b, полный импорт всегда затеняет определения внешних областей с одинаковыми именами. В R2019a и более ранних версиях полный импорт игнорировался при затенении идентификатора во внешней области.
| Начиная с R2019b | Обновленный код | R2019a и более ранние |
|---|---|---|
Локальная функция function myfunc x = 1; function nest % Import function x import pkg1.x % Calls pkg1.x x() end end | Использование переменной function myfunc x = 1; nest(x) function nest(x1) % Import function x import pkg1.x % Calls pkg1.x with % variable x1 x(x1) end end | В этом коде функция function myfunc x = 1; function nest % Import function x import pkg1.x % x is a variable x() end end |
Начиная с R2019b, полный импорт, который не может быть разрешен, приводит к ошибке с Java ® или без нее. В R2019a и более ранних версиях MATLAB вел себя по-разному в зависимости от запуска MATLAB с помощью -nojvm вариант. Не используйте такие функции, как javachk и usejava для настройки сообщений об ошибках.
| Начиная с R2019b | Обновленный код | R2019a и более ранние |
|---|---|---|
Этот код вызывает ошибку при запуске MATLAB с помощью function myfunc import java.lang.String % Errors if ~usejava('jvm') % Statement never executes disp('This function requires Java'); else % Do something with Java String class end end | Удалить вызов function myfunc import java.lang.String % Errors % Do something with java String class end | Этот код отображает сообщение при запуске MATLAB с помощью function myfunc import java.lang.String if ~usejava('jvm') % Display message disp('This function requires Java'); else % Do something with Java String class end end |
Начиная с R2019b вложенные функции наследуются import инструкции из родительской функции. В R2019a и более ранних версиях вложенные функции не наследовали инструкции импорта от родительских функций.
| Начиная с R2019b | R2019a и более ранние |
|---|---|
function myfunc % Package p1 has functions plot and bar import p1.plot import p1.* nest function nest plot % Calls p1.plot bar % Calls p1.bar end end |
function myfunc % Package p1 has functions plot and bar import p1.plot import p1.* nest function nest plot % Calls plot function on path bar % Calls bar function on path end end |
Начиная с R2019b, MATLAB разрешает составные имена по-другому. Составное имя состоит из нескольких частей, соединенных точкой (например, a.b.c), который может использоваться для ссылки на элементы пакета. С помощью R2019b MATLAB разрешает составные имена, придавая приоритет самому длинному префиксу соответствия. В предыдущих выпусках порядок приоритета следовал более сложному набору правил.
Например, предположим, что пакет pkg содержит класс foo со статическим методом bar а также субпакет foo с функцией bar.
+pkg/@foo/bar.m % bar is a static method of class foo +pkg/+foo/bar.m % bar is a function in subpackage foo
В R2019b, вызов which pkg.foo.bar возвращает путь к функции пакета.
which pkg.foo.bar+pkg/+foo/bar.m
Ранее статический метод имел приоритет над функцией пакета в случаях, когда пакет и класс имели одинаковые имена.
Начиная с R2019b, анонимные функции могут включать как разрешенные, так и неразрешенные идентификаторы. В предыдущих версиях, если какие-либо идентификаторы в анонимной функции не были разрешены во время создания, все идентификаторы в этой анонимной функции были неразрешены.
| Начиная с R2019b | R2019a и более ранние |
|---|---|
Для оценки анонимной функции MATLAB вызывает локальную функцию. function myfun myscript; % Includes x = 1 and lf = 10 f = @()lf(x); f() % Displays 'Inside lf' end % Local function to myfun function lf(y) disp('Inside lf'); end | MATLAB рассматривает function myfun myscript; % Includes x = 1 and lf = 10 f = @()lf(x); f() % Displays 10 end % Local function to myfun function lf(y) disp('Inside lf'); end |