【问题标题】:How do nested functions work in MATLAB?嵌套函数如何在 MATLAB 中工作?
【发布时间】:2014-12-02 00:38:32
【问题描述】:

所以,我是applying for a job,需要弄清楚how nested functions work。更具体地说,我想确切地知道gnovice 发布的以下示例是如何工作的。

问题是:

给定下面的函数,在命令窗口中输入下面的代码会输出什么?

function fcnHandle = counter
  value = 0;
  function currentValue = increment
    value = value+1;
    currentValue = value;
  end
  fcnHandle = @increment;
end

f1 = counter();
f2 = counter();
output = [f1() f1() f2() f1() f2()];  %# WHAT IS IT?!

我没有申请工作,我能够找出问题的答案。我还直观地找到了从Mohsenthis questionthe answer(无需调用内置函数即可找到矩阵的大小)。然而,我不禁在脑海中听到阿尔伯特爱因斯坦的声音。

我认为documentation 有点乱,所以如果有人能够解释它是如何工作的,我会非常高兴。

【问题讨论】:

  • +1 在您的脑海中听到! :-)

标签: matlab nested-function


【解决方案1】:

这种嵌套函数的使用与记忆相关(更多阅读请参见:use nested functions to memoize costly functions),因为它利用了parametric function handles,它在创建时存储了参数的值。

有两点需要注意:

  1. counter() 直接返回嵌套函数的函数句柄

    f1 = counter()
    f1 = 
       @counter/increment
    
  2. 嵌套函数将“保存”作用域变量。详情请参考functions()

    s = functions(f1)
    s = 
         function: 'counter/increment'
             type: 'nested'
             file: '\\ic.ac.uk\homes\ok1011\MATLAB\counter.m'
        workspace: {[1x1 struct]}
    

    保留范围内的工作空间:

    s.workspace{1}
    ans = 
        fcnHandle: @counter/increment
            value: 0
    

基本上,counter()value 初始化为零,对@counter/increment 的连续调用将执行value = value+1;

最后,@counter/increment 被分配给f1,而所有f1() 所做的就是@counter/increment() 在先前初始化的value 上。初始化f2 = counter(),使用单独保存的workspace 创建另一个计数器。

【讨论】:

  • 我更喜欢这个解释。它显示了实际发生的内部情况。 +1。
【解决方案2】:

让我试试....

每次调用函数counter() 都会创建一个唯一的函数句柄。这个函数句柄是一个名为 increment 的函数的句柄,它接受自己的变量值,并将其递增 1。

因此,如果调用两次,就像代码中的 (f1, f2) 一样,每次都会返回相同的函数(增量)但不同的句柄。您已经定义了 TWICE 函数。现在他们每个人都独立工作。由于此特定函数(增量)依赖于保存的内部值进行计算,因此您可以观察在代码示例中调用时如何输出 [1 2 1 3 2]。

更好地看出差异的一个好方法是将函数重新定义为:

function fcnHandle = counter(val)
  value = val;
  function currentValue = increment
    value = value+1;
    currentValue = value;
  end
  fcnHandle = @increment;
end

然后这样称呼它:

>> f1 = counter(0);
>> f2 = counter(1000);
>> output = [f1() f1() f2() f1() f2()]  %# WHAT IS IT?

现在,你会看到输出是[1 2 1001 3 1002]

现在更有意义了吗?

创建此代码是为了利用函数句柄的这个属性(它是相同的东西,但它被复制了两次)。

【讨论】:

    【解决方案3】:

    整齐的运动。我以前从未使用过带句柄的嵌套函数,所以这是我的思考过程: 我在the manual 中发现这一段很有启发性:

    嵌套函数可以使用来自三个来源的变量:

    Input arguments
    
    Variables defined within the nested function
    
    Variables defined in a parent function, also called externally scoped variables
    

    当您为嵌套函数创建函数句柄时,该句柄 不仅存储函数的名称,还存储函数的值 外部作用域变量。

    所以在示例中,函数counter 将变量value 设置为0,然后调用incrementincrement 存储 value 在其句柄中,因此每次调用 increment 时,value 都会递增并覆盖 value=0 的第一个定义。

    因此,输出是0 加上调用increment 的次数,即每次调用counter 的给定实例。

    当你写这个时:

    f1 = counter();
    f2 = counter();
    

    您创建两个独立的函数 counter 实例,它们将独立递增。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2020-03-07
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多