如果函数也是MATLAB中的变量会发生什么?

时间:2016-03-29 15:40:21

标签: matlab variables namespaces keyword

标题可能听起来很奇怪。所以这是一个例子。

Say .scss是一个在MATLAB中广泛使用的关键字或内部函数,有人保存了一个名为length的变量。

我可以运行以下脚本而不会出现任何问题,但是如果我将它放在一个函数中就会产生错误(使用R2015b)

有效的脚本

length

不起作用的功能

clear length;
length = [1 2 4];
la = length;
clear length;
b = length(la);
  

错误:引用已清除的变量长度。

为什么会这样? MATLAB如何以不同方式处理这些情况?这应该发生在其他功能/关键字上吗?

1 个答案:

答案 0 :(得分:10)

问题

根据提供的描述in this answer,MATLAB实际解析函数并在实际执行函数之前确定函数的范围。因此,它想知道(在运行函数之前)是否打算将length用作函数或变量。在您的情况下,它会看到您将其用作变量,因此无法将其用作函数,即使清除变量也是如此。

演示

  1. 实际上,如果我们执行以下操作,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。

  2. 现在,如果我们更改我们的功能,以便我们首先调用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的变量,并且无法提醒您这种意外行为。

  3. 现在您注意到,使用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
    
  4. 摘要

    所以这实际意味着,如果你在函数中定义一个名为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