它与Matlab如何在编译时执行名称绑定有关.因为matlabBugTest有一行为a赋值,所以a被确定为变量,而后一行带有a是对该变量的引用而不是对本地函数的调用.更现代的Matlab版本,比如我的R2015a安装,提供了更清晰的错误信息:
At compilation, “a” was determined to be a variable and this variable is uninitialized. “a” is also a function name and previous versions of MATLAB would have called the
function. However, MATLAB 7 forbids the use of the same name in the same context as both a function and a variable.
这不是一个错误,因为它是由命名方案引入的歧义,给出了一个默认的解决方法,如果你之前从未遇到过问题并且m-lint没有标记它,这可能很烦人.当variables are poofed into the workspace未事先初始化时,会发生类似的行为.
因此,解决方案是将函数或变量的名称更改为不同的东西,我认为这是好的做法.
在考虑你的后续例子时,我注意到在函数中移动事物时有一些有趣的行为.首先,如果函数是外部函数或嵌套函数,你会得到很好的讨论by Suever’s answer.但是,如果函数是本地的,你可以通过调用函数来绕过限制(至少你可以在我的R2014b和R2015a安装中)在将其转换为变量之前,只要将其初始化或在某个时刻将其显式转换为变量即可.通过这些案例,matlabBugTest的以下主体如此执行:
>失败:
a
if false
a = 'foo';
end
a
>运行:
a
if true
a = 'foo';
end
a
>运行:
a = a;
if false % runs with true as well.
a = 'foo';
end
a
我不完全确定为什么这种行为是这样的,但显然解析器根据函数的范围和符号出现的顺序以及在什么上下文中处理不同的事情.
所以假设这种行为没有也不会改变你可以尝试这样的事情:
pathConstant = pathConstant;
if ~exist('pathConstant.m', 'file')
pathConstant = 'C:\some\path';
end
load(fullfile(pathConstant, 'filename.ext'));
虽然,完全是个人意见,我会做类似的事情
pathConstant = getPathConstant();
if ~exist('pathConstant.m', 'file')
pathConstant = 'C:\some\path';
end
load(fullfile(pathConstant, 'filename.ext'));
关于打破“函数和脚本/命令行之间的兼容性”,我并不认为这是一个问题,因为当涉及到Matlab时,它们是两个完全不同的上下文.您无法在命令行或脚本文件中定义命名函数;因此,Matlab JIT没有任何负担可以正确无误地确定符号是函数调用还是变量,因为每行都是按顺序执行而不是编译(除了某些代码块之外,JIT设计用于识别和优化脚本中的循环).现在,为什么上面的声明工作起作用,我不完全确定,因为它依赖于Matlab JIT,我一无所知(我也没有参加过编译器课程,所以如果我不能形成学术上的理由通缉).