问题描述
标题听起来很奇怪.所以这是例子.
The title may sound strange. So here is the example.
说length
是在MATLAB中广泛使用的关键字或内部函数,有人保存了一个名为length
的变量.
Say length
is a keyword or internal function that is widely used in MATLAB and someone saved a variable called length
.
我可以运行以下脚本而没有任何问题,但是如果将其放在函数中,则会产生错误(使用R2015b)
I can run the following script without any issues, but if I place it within a function it produces an error (using R2015b)
有效的脚本
clear length;
length = [1 2 4];
la = length;
clear length;
b = length(la);
该功能无效
function test(a)
length = [1 2 4];
save('data.mat','length');
clear length;
load('data.mat');
% load
la = length;
clear length;
b = length(la);
end
为什么会这样? MATLAB如何以不同的方式对待这些情况?其他功能/关键字是否应该发生这种情况?
Why does this happen? How does MATLAB treat these situations differently? Should this happen to other functions/keywords?
推荐答案
问题
根据此答案中提供的描述,MATLAB实际上会解析该函数并确定该函数的范围之前它实际上执行了该功能.因此,它想知道(在运行函数之前)您打算将length
用作函数还是变量.在您的情况下,它会看到您将其用作变量,因此即使清除了该变量,您也不能将其用作函数.
The Issue
Based on the description provided in this answer, MATLAB actually parses the function and determines the scope of the function before it actually executes the function. As such, it wants to know (prior to running a function) whether you intend to use length
as a function or variable. In your case, it sees that you are using it as a variable, and therefore you cannot use it as a function even if you clear the variable.
-
因此,实际上,如果我们执行以下MATLAB,则将根本无法调用函数:
So actually, if we do the following MATLAB will fail to call our function at all:
function test()
%// Use length the function
L = length([1,2,3]);
%// Now use length as a variable
length = 2;
end
现在,如果我们更改函数,以便首先调用length
作为函数,然后加载文件并尝试访问变量 length
(已隐式初始化)和load
)
Now, if we change our function so that we first call length
as a function, then load our file and try to access the variable length
(which was initialized implicitly with load
)
function test()
%// Use the function length
L = length([1,2,3]);
%// Load the variable length
load('data.mat')
la = length;
end
因为MATLAB事先确定了函数的范围,所以它只看到了 function length
,这会阻止length
稍后在函数中用作变量,即使您尝试执行以下操作:从文件加载它.这样,当您尝试访问变量 length
时,其行为就像您在没有输入的情况下调用了 function length
一样.
Because MATLAB determined the scope of the function beforehand, it only saw the function length
and this prevents length
from being used as a variable later in the function, even when you attempt to load it from the file. That way, when you tried to access the variable length
it behaves as if you had called the function length
with no inputs.
我们没有从#1看到相同错误的原因是因为MATLAB无法知道data.mat
包含名为length
的变量,并且无法提醒您这种意外行为.
The reason we didn't see the same error from #1 is because MATLAB had no way of knowing that data.mat
contained a variable named length
and couldn't alert you of this unexpected behavior.
现在,使用eval
实际上允许您访问变量.为什么,我不确定,但是eval
的作用域很可能是在您调用时确定的,并且不受父函数的作用域规则的约束.
Now as you noticed, using eval
actually allows you to access the variable. Why this is, I'm not completely sure but it likely that the scope for eval
is determined when you call it and isn't subject to the scope rules of the parent function.
eval
似乎试图确定是否在运行时使用length
的函数或变量版本,因为我们可以从同一函数中确认它们.
It appears that eval
tries to determine whether to use the function or variable version of length
at runtime as we can get it to acknowledge both from within the same function.
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将确定先于运行函数,从而阻止您将length
用作相同功能中的 function .使用脚本或在命令窗口中时不会出现此问题,因为作用域是在运行时计算的,并且length
既可以用作变量也可以用作函数(假定在调用函数clear length >).
Summary
So what this effectively means, is that if you define a variable named length
in your function, MATLAB will determine that prior to running your function, preventing you from ever using length
as a function within that same function. This issue does not appear when working with a script or at the command window because the scope is computed at runtime and length
can be used as both a variable and function (given that you call clear length
prior to calling the function length
).
最佳做法是始终 指定输出到load
.然后,将数据作为struct
加载,而不是使用文件中存储的所有变量来污染当前的工作空间.那么用户变量的名称无关紧要,可以保证它不会与您的任何变量或MATLAB的内置函数发生冲突,并且可以避免意外的行为.
Best practice is to always specify an output to load
. Then the data is loaded in as a struct
rather than polluting your current workspace with all of the variables stored within the file. Then it doesn't matter what the user named a variable, it is guaranteed to not conflict with any of your variables or MATLAB's built-in functions and you can avoid unexpected behavior.
data = load('data.mat');
la = data.length;
这还确保MATLAB能够正确确定函数的范围,因为它可以看到您有一个名为data
的变量,并且data.mat
的所有内容都将加载到该变量中.
This also ensures that MATLAB is able to properly determine the scope of your function since it can see that you have a variable named data
and all contents of data.mat
will be loaded into this variable.
如果要保持原样,但在加载文件后仍可以访问内置的length
函数(无需指定输出参数).您可以使用builtin
访问 real length
函数.
If you want to keep things the way that they are but still have access to the built-in length
function after loading the file (without specifying an output argument). You can use builtin
to access the real length
function.
b = builtin('length', la);
这篇关于如果函数也是MATLAB中的变量,会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!