Обновление кода для R2019b изменений в порядок приоритета функций

Начиная с R2019b, MATLAB изменяет правила разрешения имен, влияя на порядок приоритета переменных, вложенных функций, локальных функций и внешних функций. Новые правила упрощают и стандартизируют разрешение имен. Для получения дополнительной информации смотрите Порядок приоритета функций.

Эти изменения влияют на поведение import функция. Вам следует проанализировать и, возможно, обновить код. Чтобы начать, найдите в коде операторы импорта. Для примера используйте Поиск файлов и папок для поиска .m и .mlx файлы, содержащие текстовые import. Обратитесь к этим результатам поиска при оценке эффектов следующих изменений.

Идентификаторы не могут использоваться в двух целях внутри функции

Начиная с R2019b, ошибка возникает, если вы используете идентификатор, сначала как локальную или импортированную функцию, а затем как переменную. В предыдущих релизах идентификатор может использоваться в различных целях в областях видимости функции, что приводит к неоднозначному коду.

Если это изменение поведения влияет на ваш код, переименуйте переменную или функцию так, чтобы они имели другие имена.

Начиная с R2019bОбновленный кодR2019a и более ранние версии

Имя local используется в качестве local функцию, а затем переменную. Эти ошибки кода.

function myfunc
% local is an undefined variable
local(1); % Errors
local = 2; 
disp(local);
end

function local(x)
disp(x)
end

Переименуйте функцию local на localFcn.

function myfunc
localFcn(1);
local = 2; 
disp(local);
end

function localFcn(x)
disp(x)
end

Этот код отображает 1 затем 2.

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.

Начиная с R2019bR2019a и более ранние версии
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

Вызов функции nest от import оператор, переименуйте локальную функцию myfunc/nest.

function myfunc
import pkg.nest 
nest();          

    function newNest
    end
end

Эта функция вызывает функцию nest от import оператор.

function myfunc
import pkg.nest   
nest();  % Calls pkg.nest

    function nest
    end
end

Эта функция ошибается из-за объявления переменной с таким же именем, как и импортированная функция nest не поддерживается.

function myvarfunc
import pkg.nest  % Errors 
nest = 1
end

Переименуйте переменную nest.

function myvarfunc
import pkg.nest  % Errors 
thisNest = 1
end

Эта функция изменяет переменную nest.

function myvarfunc
import pkg.nest
nest = 1  % Modifies variable nest and
          % displays warning since R2018a
end

Полный импорт теневых определений внешних возможностей с таким же именем

Начиная с R2019b, полный импорт всегда затеняет определения внешних возможностей с таким же именем. В R2019a и более ранних версиях полный импорт игнорировался, когда он затенял идентификатор во внешних возможностях.

Начиная с R2019bОбновленный кодR2019a и более ранние версии

Локальные функциональные nest вызывает функцию x из импортированного пакета.

function myfunc
x = 1;

    function nest
        % Import function x
        import pkg1.x 
        % Calls pkg1.x 
        x()
    end
end

Как использовать переменные x в локальных функциональных nest, передайте переменную в качестве аргумента.

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

В этом коде функционируйте nest игнорирует импортированную функцию x.

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 с -nojvm опция.

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

Удалите вызов usejava.

function myfunc 
import java.lang.String % Errors
% Do something with java String class 
end

Этот код отображает сообщение при запуске MATLAB с -nojvm опция.

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 и более ранних версиях вложенные функции не наследовали операторы импорта от своих родительских функций.

Начиная с R2019bR2019a и более ранние версии
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, анонимные функции могут включать как разрешенные, так и неразрешенные идентификаторы. В предыдущих релизах, если какие-либо идентификаторы в анонимной функции не были разрешены во время создания, все идентификаторы в этой анонимной функции были неразрешены.

Начиная с R2019bR2019a и более ранние версии

Чтобы оценить анонимную функцию, MATLAB вызывает локальную функцию lf с x определено в myscript потому что lf в анонимной функции разрешается локальная функция.

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 рассматривает lf как неразрешенный идентификатор наряду с x, и используемые x для индекса в переменную lf от myscript.

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 

См. также

Похожие темы