如果函数也是MATLAB中的变量,会发生什么? [英] What happens if a function is also a variable in MATLAB?

查看:263
本文介绍了如果函数也是MATLAB中的变量,会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题听起来很奇怪.所以这是例子.

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

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

error: Reference to a cleared variable length.

为什么会这样? 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.

  1. 因此,实际上,如果我们执行以下MATLAB,则将根本无法调用函数:

  1. 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

错误:文件:test.m行:6列:6
长度"以前似乎被用作功能或命令,与此处用作命令"时存在冲突. 变量的名称.
发生此错误的可能原因是您忘记了初始化变量,或者您已经初始化了 隐式使用load或eval.

Error: File: test.m Line: 6 Column: 6
"length" previously appeared to be used as a function or command, conflicting with its use here as the name of a variable.
A possible cause of this error is that you forgot to initialize the variable, or you have initialized it implicitly using load or eval.

  • 现在,如果我们更改函数,以便首先调用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
    

    使用长度错误
    输入参数不足.

    Error using length
    Not enough input arguments.

    因为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中的变量,会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆