【问题标题】:MATLAB name clash: "wrong number of arguments"MATLAB 名称冲突:“参数数量错误”
【发布时间】:2012-05-02 11:36:35
【问题描述】:

我的 MATLAB 名称似乎与我的一个名为“annotation”的变量和内置的 MATLAB 函数“annotation”发生冲突。

在我的函数中,我正在加载一个包含变量注释的 .mat 文件,然后尝试将其用作另一个函数的参数。一个最小的工作示例如下所示:

function test()

    filenames = { 'file1.mat', 'file2.mat', 'file3.mat' };

    for i = 1:numel(filenames)
        in_file = char(filenames{i});
        out_file = strrep(in_file, '.mat', '_out.mat');

        prepare(out_file); % do something with the out file

        load(out_file);  % contains one variable named "annotation"
        which annotation % just to be sure

        other_function(annotation);
    end
end

function prepare(filename)
    annotation = rand(25, 1);
    save(filename);
end

function other_function(annotation)
    whos % just a stub - see whether it has been called
end

现在,在我的函数准备中,我确保文件包含一个名为“annotation”的变量。当我在主函数的循环中加载它时,“which”命令告诉我它作为变量存在,但在调用 other_function 时,MATLAB 尝试调用函数“annotation”:

注解是一个变量。

???在 71 处使用 ==> 注释时出错

没有足够的输入参数

==> 14 点测试出错

        other_function(annotation);

我很困惑,因为我在我的程序的几个部分中使用了变量名“annotation”,也作为函数调用中的参数。我能想象的唯一解释是 MATLAB 以某种方式预编译了我的代码——在“编译时”,变量“注释”是不可见的。但是,在运行时可以从“which”命令的输出中看到它。

任何帮助将不胜感激!非常感谢。

注意:我使用的是 MATLAB 7.12.0 (R2011a)。

【问题讨论】:

  • 即使您在其他情况下取得了成功,我要做的只是更改变量注释的名称。好吧,我无法将注释视为您声明的代码中的变量。据我了解Matlab,它只是覆盖所有内容而无需询问,因为它是脚本语言。你能通过调试器看看“which”的注释里面有什么吗?
  • 调试器会说注解是一个变量,如果你在调试器中输入annotation,它会计算它而不会出错。

标签: function matlab


【解决方案1】:

这是一个非常晦涩难懂的问题!这是 Mathwork 的糟糕设计。我什至会称其为错误,看看他们是否同意很有趣。

简短的回答:您可以通过在代码中的任何位置添加annnotation = 2; 行来“修复”此问题load(out_file); 行上方。或者annotation = "roger"; 或者annotation = false;,不管你注释什么类型的变量,只要你明确地强制它成为你代码中的一个变量。

您编写的代码没有明确引用变量annotationannotation 恰好是您加载到函数工作区的 matlab 文件中的变量名称。不知何故,这不会引发运行时错误,它只是工作错误,我称之为错误,但 matlab 可能会说这是一个记录的限制。在http://www.mathworks.com/help/techdoc/matlab_prog/f4-39683.html#f4-75258 上查看他们的文档并告诉我您的想法。该文档似乎适用于嵌套函数,而您的 main 函数肯定不是。很明显,您的行 other_function(annotation) 应该看到 annotation 与位于其上方的 which annotation 相同的范围内。 (我刚刚做了那个测试,上面写着annotation is a variable)。

这是一个显示问题的最小程序:

function test()
  prepare('test.mat'); % writes i
  load('test.mat');  % contains one variable named "annotation"

  which annotation
  other_function(annotation);
end

function prepare(filename)
  annotation = 42; % the answer is 42
  save(filename);
end

function other_function(poodle)
  disp(poodle);
end

我邀请您使用该页面上的“报告错误”链接将其作为错误报告提交至http://www.mathworks.com/support/bugreports!如果您不想,我会举报,请告诉我。

【讨论】:

  • 感谢您就如何处理该问题提出建议!我同意你的观点,文档只讨论嵌套和“在某些情况下”匿名函数。此外,在最小示例中,函数 prepare 是一个子函数,但在我发现该问题的原始代码中,它甚至是一个主函数。我试图就此提交错误报告,但不幸的是
  • 我试图就此提交错误报告,但不幸的是 Mathworks 网站不允许我(之前遇到过这个问题,我的浏览器和 cookie 有问题...)。如果您可以这样做,那就太好了,并将链接发送给我,我可以在其中关注此错误。
  • 我已提交bug report。我的标题却是函数调用访问函数而不是局部变量。
【解决方案2】:

这有点奇怪!我发现了同样的事情。基本上,工作区变量不应该在内部函数的范围内(尽管它们来自内部脚本)。

如果您执行load(out_file),则将该文件的内容加载到工作区中。所以他们不应该在范围内,我相信。因此,我对which(annotation) 将其称为变量感到惊讶,但对annotation 超出范围并不感到惊讶。 (实际上,Matlab 似乎确实将变量放在范围内。)

我认为您关于对annotation 进行某种预处理的想法听起来很合理。例如,如果您将other_function(annotation) 替换为eval('other_function(annotation);'),那么它可能会起作用(尽管我并不是说您应该永远使用eval)。

解决此问题的最佳方法是执行以下操作:

data = load(out_file);
annotation = data.annotation;

所以,将out_file 加载到结构中,然后从那里访问变量。

【讨论】:

  • 谢谢,这绝对是个好主意。这也将使我的代码更易于理解,因为变量注释是显式声明的。
【解决方案3】:
猜你喜欢
  • 1970-01-01
  • 2019-11-23
  • 2020-06-18
  • 1970-01-01
  • 2017-07-13
  • 2013-04-14
  • 2015-11-09
  • 2011-04-15
  • 2012-10-01
相关资源
最近更新 更多