标题可能听起来很奇怪。所以这是一个例子。
Say .scss
是一个在MATLAB中广泛使用的关键字或内部函数,有人保存了一个名为length
的变量。
我可以运行以下脚本而不会出现任何问题,但是如果我将它放在一个函数中就会产生错误(使用R2015b)
有效的脚本
length
不起作用的功能
clear length;
length = [1 2 4];
la = length;
clear length;
b = length(la);
错误:引用已清除的变量长度。
为什么会这样? MATLAB如何以不同方式处理这些情况?这应该发生在其他功能/关键字上吗?
答案 0 :(得分:10)
根据提供的描述in this answer,MATLAB实际解析函数并在实际执行函数之前确定函数的范围。因此,它想知道(在运行函数之前)是否打算将length
用作函数或变量。在您的情况下,它会看到您将其用作变量,因此无法将其用作函数,即使清除变量也是如此。
实际上,如果我们执行以下操作,MATLAB将无法调用我们的函数:
function test()
%// Use length the function
L = length([1,2,3]);
%// Now use length as a variable
length = 2;
end
错误:文件:test.m行:6列:6
“长度”以前似乎被用作函数或命令,与此处的使用冲突 变量的名称 导致此错误的可能原因是您忘记初始化变量,或者您已初始化 它隐含地使用load或eval。
现在,如果我们更改我们的功能,以便我们首先调用length
作为函数,然后加载我们的文件并尝试访问变量 length
(用load
)隐式初始化
function test()
%// Use the function length
L = length([1,2,3]);
%// Load the variable length
load('data.mat')
la = length;
end
使用长度时出错 没有足够的输入参数。
因为MATLAB事先确定了函数的范围,所以它只看到函数 length
,这可以防止length
在函数后面被用作变量,甚至当您尝试从文件加载它时。这样,当您尝试访问变量 length
时,其行为就像您在没有输入的情况下调用函数 length
一样。
我们没有从#1看到相同错误的原因是因为MATLAB无法知道data.mat
包含名为length
的变量,并且无法提醒您这种意外行为。
现在您注意到,使用eval
实际上允许您访问变量。为什么会这样,我不完全确定,但eval
的范围很可能在您调用它时确定,并且不受父函数范围规则的约束。
似乎eval
试图确定是否在运行时使用length
的函数或变量版本,因为我们可以在同一函数中确认它们。
function test()
%// Use the function length
L = length([1,2,3]);
%// Load the variable length
load('data.mat')
%// Eval can actually access the VARIABLE length
eval('la = length;');
%// Eval can ALSO access the FUNCTION length
eval('L = length([1,2,3])');
end
所以这实际意味着,如果你在函数中定义一个名为length
的变量,MATLAB将确定 previous 运行你的函数,阻止你使用{{ 1}}作为同一函数中的函数。使用脚本或在命令窗口中不会出现此问题,因为范围是在运行时计算的,length
可以用作变量和函数(假设您在调用之前调用length
函数clear length
)。
最佳做法是始终 specify an output to load
。然后将数据作为length
加载,而不是使用存储在文件中的所有变量来污染当前工作空间。那么用户命名变量并不重要,它保证不会与您的任何变量或MATLAB的内置函数冲突,并且可以避免意外行为。
struct
这也确保了MATLAB能够正确地确定函数的范围,因为它可以看到你有一个名为data = load('data.mat');
la = data.length;
的变量,并且data
的所有内容都将加载到这个变量中。 / p>
如果你想保持它们的方式,但在加载文件后仍然可以访问内置的data.mat
函数(不指定输出参数)。您可以使用length
访问真正的 builtin
功能。
length