然后在范围之外访问在嵌套条件内声明的Matlab中的变量

时间:2014-10-21 02:09:57

标签: matlab

这在我见过的任何其他语言中都没有用:

for...
  if (...)
    if (...)
       ids = [1,2,3;4,5,6]
    end
  end
end

K = ids(:,3)

我无法在Matlab文档中找到任何参考资料,但对我来说,在C,Ruby,Javascript,PHP,Java,Python,甚至是Ada95,都应该不行。它不在函数的输入参数中,它没有在其他任何地方声明。

这种方法在附加到论文的代码中使用了两次。谁能摆脱光明? Matlab中是否只有全局范围?

2 个答案:

答案 0 :(得分:5)

我相信(尽管如果有人希望反驳我,我有兴趣学习),MATLAB变量范围仅限于函数中的定义,而不是< EM>块。因此,在该块内的if-else块内定义的变量可在该块外部访问,但仅在同一函数内可访问。基本上,每个函数都有自己的工作空间,并且在该函数中定义的变量都进入该工作空间。当我们开始使用嵌套函数等时,它会变得有点复杂,为此,我引用了非常有用的Art of MATLAB Blog

对于第二个问题,MATLAB确实具有全局范围 - 函数定义为

global var

在全局工作空间中定义,可以在MATLAB中的任何地方访问*。如果在一个函数中将变量定义为全局变量,则可以通过重复global var语句来访问另一个函数中的变量。请阅读here以获取更多信息。

*请注意,全局变量不适用于并行化代码(例如,在par-for循环中。

答案 1 :(得分:4)

首先在循环中声明和定义的变量不是全局变量,但您可以在任何地方声明变量。我不认为有一个范围比一个函数更局部。一般来说,MATLAB的范围非常广泛。我同意非global变量的范围仅限于它所定义的函数,但有几种不同寻常的方式可以传递变量MATLAB。


似乎违反通常范围规则的一个奇怪的是函数句柄。与许多其他语言不同,函数句柄只是指向内存中函数的指针,MATLAB存储函数句柄的工作空间。例如:

>> a = pi;
>> aFun = @(r) a*r.^2;
>> a = 1
>> aFun(1/sqrt(2))

ans =

    1.5708

句柄吞噬了a的初始值:

>> finfo = functions(aFun)

finfo = 

     function: '@(r)a*r.^2'
         type: 'anonymous'
         file: ''
    workspace: {[1x1 struct]}

>> finfo.workspace{1}

ans = 

    a: 3.1416

嵌套函数的函数句柄也是使变量在其原始范围之外可访问的另一种方法,包括嵌套函数本身,甚至可以在该文件之外访问它!它再次通过在创建句柄时存储值来实现。考虑一下这个功能:

function [y,hf] = nestTest(x)

    a = 2; b = 1;

    y = nestFun(x);

    hf = @nestFun;

    function y = nestFun(x)
        y = a*x + b;
    end

end

它调用嵌套函数,但也返回一个句柄。它似乎没有定义ab,但它有效:

>> [y,hf] = nestTest(2)    
y =

     5

hf = 

    @nestTest/nestFun

手柄也是如此:

>> hf(2)    
ans =

     5

同样,因为它存储了一个内部工作空间,其中包含了在定义时继承的值:

>> finfo = functions(hf)

finfo = 

     function: 'nestTest/nestFun'
         type: 'nested'
         file: 'C:\Users\Jon.bobs-tavern\Documents\MATLAB\nestTest.m'
    workspace: {[1x1 struct]}

>> finfo.workspace{1}

ans = 

     y: 5
    hf: @nestTest/nestFun
     x: 2
     a: 2
     b: 1

有关详细信息,请参阅Preserving Data from the Workspace。此外,MATLAB编辑器有highlighting to help indicate scope


要记住的另一件事(其他编程语言的用户应该熟悉)是堆栈(或变量存在的工作空间)。您可以使用assignin直接将变量分配给调用者或“基础”工作区。