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