如果函数也是 MATLAB 中的变量会怎样? [英] What happens if a function is also a variable in MATLAB?

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

问题描述

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

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

我可以毫无问题地运行以下脚本,但如果我将它放在函数中会产生错误(使用 R2015b)

有效的脚本

清除长度;长度 = [1 2 4];la = 长度;明确的长度;b = 长度(la);

不起作用的功能

功能测试(a)长度 = [1 2 4];保存('data.mat','长度');明确的长度;加载('data.mat');% 加载la = 长度;明确的长度;b = 长度(la);结尾

<块引用>

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

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

解决方案

问题

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

示范

  1. 所以实际上,如果我们执行以下操作,MATLAB 将根本无法调用我们的函数:

    函数测试()%//使用长度函数L = 长度([1,2,3]);%//现在使用长度作为变量长度 = 2;结尾

    <块引用>

    错误:文件:test.m 行:6 列:6
    长度"以前似乎被用作函数或命令,与这里用作变量的名称.
    此错误的一个可能原因是您忘记初始化变量,或者您已初始化它隐式使用 load 或 eval.

  2. 现在,如果我们改变我们的函数,以便我们首先调用 length 作为一个函数,然后加载我们的文件并尝试访问 变量 长度(使用load隐式初始化)

    函数测试()%//使用函数长度L = 长度([1,2,3]);%//加载可变长度加载('data.mat')la = 长度;结尾

    <块引用>

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

    因为 MATLAB 事先确定了函数的范围,所以它只看到 function length,这会阻止 length 被用作变量稍后在函数中,即使您尝试从文件中加载它.这样,当您尝试访问 variable length 时,它的行为就像您调用了 function length没有输入.

    我们没有从 #1 中看到相同错误的原因是因为 MATLAB 无法知道 data.mat 包含一个名为 length 的变量并且无法'不会提醒您这种意外行为.

  3. 现在您注意到了,使用 eval 实际上允许您访问变量.为什么会这样,我不完全确定,但很可能 eval 的范围是在您调用它时确定的,并且不受父函数的范围规则的约束.

    似乎 eval 试图在运行时确定是使用 length 的函数还是变量版本,因为我们可以让它在同一个函数中确认两者.

    函数测试()%//使用函数长度L = 长度([1,2,3]);%//加载可变长度加载('data.mat')%//eval实际上可以访问VARIABLE长度eval('la = 长度;');%//eval 也可以访问函数长度eval('L = 长度([1,2,3])');结尾

总结

所以这实际上意味着,如果您在函数中定义一个名为 length 的变量,MATLAB 将确定 先于 运行您的函数,从而阻止您在同一函数中使用 length 作为 function.使用脚本或在命令窗口中不会出现此问题,因为范围是在运行时计算的,并且 length 可以用作变量和函数(假设您调用 clear length 在调用函数 length 之前).

解决方案

最佳做法是始终 指定load 的输出.然后将数据作为 struct 加载,而不是使用存储在文件中的所有变量污染当前工作区.那么无论什么用户命名变量都没有关系,它保证不会与您的任何变量或 MATLAB 的内置函数发生冲突,并且您可以避免意外行为.

data = load('data.mat');la = 数据长度;

这也确保 MATLAB 能够正确确定函数的范围,因为它可以看到您有一个名为 data 的变量以及 data.mat 的所有内容将被加载到这个变量中.

如果你必须

如果您想保持原样,但在加载文件后仍然可以访问内置 length 函数(不指定输出参数).您可以使用 builtin 来访问 real length 函数.

b = builtin('length', la);

The title may sound strange. So here is the example.

Say length is a keyword or internal function that is widely used in MATLAB and someone saved a variable called length.

I can run the following script without any issues, but if I place it within a function it produces an error (using R2015b)

A script that works

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

Function that does not work

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.

Why does this happen? How does MATLAB treat these situations differently? Should this happen to other functions/keywords?

解决方案

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.

Demonstrations

  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
    

    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.

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

    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.

    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.

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

    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
    

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

The Solution

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;

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.

If you must

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天全站免登陆