Matlab 脚本运行函数出现令人费解的错误

Matlab 脚本运行函数出现令人费解的错误,matlab,Matlab,我在MatlabR2012B中遇到了一个令人费解的错误。同样是数据类型的变量名似乎表现出奇怪的行为。请看这个小例子: function [] = test1() dataset = 1; if dataset ~= 0 disp hello end end 对test1的调用会产生输出hello,正如预期的那样。 现在,我不再在函数中设置dataset的值,而是运行一个脚本 function [] = test2() myscript; if dataset ~= 0 disp

我在MatlabR2012B中遇到了一个令人费解的错误。同样是数据类型的变量名似乎表现出奇怪的行为。请看这个小例子:

function [] = test1()
dataset = 1;

if dataset ~= 0
  disp hello
end

end
对test1的调用会产生输出hello,正如预期的那样。 现在,我不再在函数中设置dataset的值,而是运行一个脚本

function [] = test2()
myscript;

if dataset ~= 0
  disp hello
end

end
其中myscript.m有一行:

dataset=1;
现在,当我调用test2时,我得到以下错误:

Undefined function 'ne' for input arguments of type 'dataset'.
Error in test2 (line 4)
if dataset ~= 0 
请原谅名为dataset的变量-我知道它也是数据类型的名称,它来自于我运行的代码。因此,似乎在test2中,Matlab创建了一个空的dataset对象,而不是使用名为dataset的变量。此外,只有在脚本中而不是在函数体中设置值时,才会出现此行为。更奇怪的是,我能做到:

>> dbstop in test2 at 4 % line of if statement
>> test2()
K>> dataset
dataset =
      1.00
K>> dataset ~= 0
ans =
 1
K>> if dataset ~= 0, disp hello; end
hello
K>> dbcont
我也犯了同样的错误!该错误在调试模式下不显示,但在正常执行中


有人能复制这个吗?这里发生了什么?

MATLAB联机帮助中有一些页面处理此问题;而且似乎是最相关的

没有明确的页面讨论MATLAB如何在编译时解析名称,但页面底部有一个小技巧:在某些情况下,加载或求值添加与函数同名的变量。除非这些变量在调用load或eval之前位于函数工作区中,否则MATLAB解析器将变量名解释为函数名

换句话说,如果解析器发现一个显式赋值给一个名称与另一个存在对象相同的变量,则本地定义优先。 在test2中,没有对变量数据集的显式赋值;因此,在编译文件时,解析器将dataset解释为类构造函数,因为解析器不会运行myscript或将myscript内联到函数中

然后在运行时,即使名为dataset的变量已被导入函数的工作区,正在运行的解释代码在与类构造函数关联的if语句中仍然具有dataset符号

如果需要,您仍然可以使用dataset变量名并从外部文件加载,但应该通过函数调用通过显式赋值来完成。例如:

dataset = initialize();
现在解析器会注意到dataset是函数initialize的任意输出,一切都会很好。事实上,如果需要,您甚至可以让initialize将数据集构造函数返回给数据集变量


1当变量是在没有明确赋值的情况下定义的,至少在我读过的一些博客上,MATLAB的人称之为“poofing”。在没有任何输出参数的情况下使用load、使用eval以及简单地运行脚本而不是函数,都可以将所有变量poof到工作区中。只要变量名在编译时不与其他正在使用的符号冲突,这就可以正常工作。

MATLAB联机帮助中有一些页面处理此问题;而且似乎是最相关的

没有明确的页面讨论MATLAB如何在编译时解析名称,但页面底部有一个小技巧:在某些情况下,加载或求值添加与函数同名的变量。除非这些变量在调用load或eval之前位于函数工作区中,否则MATLAB解析器将变量名解释为函数名

换句话说,如果解析器发现一个显式赋值给一个名称与另一个存在对象相同的变量,则本地定义优先。 在test2中,没有对变量数据集的显式赋值;因此,在编译文件时,解析器将dataset解释为类构造函数,因为解析器不会运行myscript或将myscript内联到函数中

然后在运行时,即使名为dataset的变量已被导入函数的工作区,正在运行的解释代码在与类构造函数关联的if语句中仍然具有dataset符号

如果需要,您仍然可以使用dataset变量名并从外部文件加载,但应该通过函数调用通过显式赋值来完成。例如:

dataset = initialize();
现在解析器会注意到dataset是函数initialize的任意输出,一切都会很好。事实上,如果需要,您甚至可以让initialize将数据集构造函数返回给数据集变量


1当变量是在没有明确赋值的情况下定义的,至少在我读过的一些博客上,MATLAB的人称之为“poofing”。在没有任何输出参数的情况下使用load、使用eval以及简单地运行脚本而不是函数,都可以将所有变量poof到工作区中。只要变量名在编译时不与其他正在使用的符号冲突,这就可以正常工作。

简而言之:问题在于dataset是一个函数,在没有输入参数的情况下运行它会构造一个dataset对象。如果你
如果在函数中给它赋值,MATLAB会记住这一点。如果在单独的脚本中执行此操作,MATLAB将首先执行函数。为什么MATLAB会记住函数中指定的值,而不是来自单独的脚本?我认为运行脚本就像复制粘贴其中的代码一样?还有,为什么整数值会出现在调试模式下,而不是在正常执行中?我不得不说,我现在不知道所有细节,但这与MATLAB中的解析顺序有关。@JandeGier关于解析顺序的说法可能是正确的。dataset对于matlab来说必须是其他含义,因为如果将变量名更改为其他名称,错误将消失,代码运行正常。是的,使用不同的变量名,它可以工作,并且在脚本运行之前添加行dataset=0,它也可以工作。如果有人知道的话,我想了解更多幕后发生的事情。简言之:问题是dataset是一个函数,在没有输入参数的情况下运行它会构造一个dataset对象。如果在函数中为它赋值,MATLAB会记住这一点。如果在单独的脚本中执行此操作,MATLAB将首先执行函数。为什么MATLAB会记住函数中指定的值,而不是来自单独的脚本?我认为运行脚本就像复制粘贴其中的代码一样?还有,为什么整数值会出现在调试模式下,而不是在正常执行中?我不得不说,我现在不知道所有细节,但这与MATLAB中的解析顺序有关。@JandeGier关于解析顺序的说法可能是正确的。dataset对于matlab来说必须是其他含义,因为如果将变量名更改为其他名称,错误将消失,代码运行正常。是的,使用不同的变量名,它可以工作,并且在脚本运行之前添加行dataset=0,它也可以工作。如果有人知道的话,我想更多地了解引擎盖下正在发生的事情。