Рабочие области для вложенных и анонимных функций являются статическими. Это означает, что все переменные, используемые в функции, должны присутствовать в тексте кода.
Если вы пытаетесь динамически добавить переменную в статическую рабочую область анонимной функции, вложенной функции или функции, которая содержит вложенную функцию, то MATLAB® выдает ошибку формы
Attempt to add variable to a static workspace.
Для получения дополнительной информации о различиях между основой и рабочими областями функции смотрите Основу и Function Рабочих областей. Для получения дополнительной информации о вложенных функциях см. Раздел «Вложенные функции».
Один из способов избежать динамического добавления переменной в статические рабочие области - явное объявление переменной в коде перед динамическим присвоением значения этой переменной. Это приведет к тому, что имя переменной станет видимым для MATLAB, поэтому имя будет включено в фиксированный набор переменных, составляющих статическую рабочую область.
Например, предположим, что скрипт с именем makeX.m динамически присваивает значение переменной X. Функция, которая вызывает makeX
и явно заявляет X избегает динамической ошибки добавления, поскольку X находится в рабочей области функции.
Общим способом объявления переменной является инициализация ее значения как пустой массив:
function noerror nestedfx function nestedfx X = []; makeX end end
eval, evalin, или assignin Назначение новых переменных во вложенной функцииИспользование eval, evalin, или assignin назначение новых переменных внутри вложенных функций вызовет ошибку.
function staticWorkspaceErrors
function nest
% This will error since x is not declared outside of the eval
eval("x=2");
end
endПо возможности избегайте этих функций вообще. См. Альтернативные варианты функции eval. Если избежать их не удается, то явным образом объявите переменную внутри родительской функции:
function noStaticWorkspaceErrors x = []; function nest % This will not error since 'x' is declared outside of the eval eval("x=2"); end end
Вызов скрипта MATLAB, который создает переменную внутри вложенной функции, вызовет ошибку. В приведенном ниже примере скрипт, scriptThatIntroducesZ, содержит код, который присваивает значение переменной z. Поскольку код явно не объявляет, что z назначается ошибка, которая будет выдана.
function staticWorkspaceErrors
function nest
% This will error since 'z' is not declared outside of this script
scriptThatIntroducesZ
end
endЧтобы избежать ошибки, объявите переменную в функции перед вызовом скрипта, который присваивает ей значение.
function noStaticWorkspaceErrors function nest % This will not error since 'z' is declared outside of the script z = []; scriptThatIntroducesZ end end
Также преобразуйте скрипт в функцию и сделайте z это выходной аргумент. Этот подход также делает код более ясным.
load ФункцияИспользование load назначение переменных внутри вложенной функции без явного указания имени переменной приведет к возникновению ошибки. В приведенном ниже примере load используется для загрузки MAT-файла, содержащего переменную Y. Поскольку код явно не объявляет, что Y назначается ошибка, которая будет выдана.
function staticWorkspaceErrors
function nest
% This will error since var Y is not explicitly specified
load MatFileWithVarY
end
endЧтобы избежать ошибки, вместо этого укажите имя переменной как вход в load функция.
function noStaticWorkspaceErrors function nest % This will not error since variables 'x' and 'y' are specified load MatFileWithVarX x y = load('MatFileWithVarY','y'); end end
Кроме того, присвойте выход из load функция в массив структур.
Во время отладки вы не можете добавить переменную с помощью командной строки debug, если вы остановлены во вложенной функции. Назначьте переменную в базовое рабочее пространство, которое не является статическим.
K>> assignin('base','X',myvalue)Анонимные функции не могут содержать переменные назначения. При вызове анонимной функции выдается ошибка.
% This will error since 'x' is being assigned inside
% the anonymous function
@()eval("x=2")Перепишите функцию таким образом, чтобы переменные назначения не требовались.
xEquals2 = @()2; x = xEquals2()
x =
2