Рабочие области для вложенных и анонимных функций являются статическими. Это означает, что все переменные, используемые в функции, должны присутствовать в тексте кода.
При попытке динамического добавления переменной в статическую рабочую область анонимной функции, вложенной функции или функции, содержащей вложенную функцию, MATLAB ® выдает ошибку формы
Attempt to add variable to a static workspace.
Дополнительные сведения о различиях между базовыми и функциональными рабочими областями см. в разделе Базовые и функциональные рабочие области. Дополнительные сведения о вложенных функциях см. в разделе Вложенные функции.
Одним из способов избежать динамического добавления переменной в статические рабочие области является явное объявление переменной в коде перед динамическим назначением значения этой переменной. При этом имя переменной станет видимым для 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По возможности избегайте этих функций в целом. См. раздел Альтернативы функции оценки. Если избежать их невозможно, то явным образом объявите переменную в родительской функции:
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