解决错误:尝试向静态工作区添加变量。
问题
嵌套函数和匿名函数的工作区是静态工作区。这意味着在函数中使用的所有变量都必须出现在代码文本中。
如果您尝试向匿名函数、嵌套函数或包含嵌套函数的函数的静态工作区中动态添加变量,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
请尽可能避免同时使用这些函数。请参阅eval 函数的替代方法。如果无法避免,则在父函数中显式声明变量:
function noStaticWorkspaceErrors x = []; function nest % This will not error since 'x' is declared outside of the eval eval("x=2"); end end
使用 MATLAB 脚本在嵌套函数中对新变量赋值
调用在嵌套函数内创建变量的 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
用于加载包含变量 Y
的 MAT 文件。由于代码未显式声明将被赋值的 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
函数到结构体数组的输出赋值。
在 MATLAB 调试器中对嵌套函数中的变量赋值
调试时,如果在嵌套函数中停止,则无法使用调试命令提示符添加变量。在基础工作区中对变量赋值,该工作区为静态工作区。
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