嵌套函数的函数句柄不适用于某些参数值

function handle to nested function not working for some values of parameter

这个函数本应return一个函数句柄到里面的嵌套函数,但是如果在外部函数中变量x被设置为负值,它就不起作用了。

内部嵌套函数只是一个常量函数return在外部函数中设置的变量 x 的值。

function t=test(x)
    x=-1;
    function y=f()
        y=x;
    endfunction
    t=@f;
endfunction

如果我尝试计算 returned 函数,例如test()(3),我收到关于 x 未定义的错误。如果 x 被定义为具有至少一个负数条目的向量,或者如果 x 是函数的参数并且负默认值用于评估,则会发生同样的情况。但是如果我将它定义为一些非负值

function t=test(x)
    x=1;
    function y=f()
        y=x;
    endfunction
    t=@f;
endfunction,

那么 returned 函数就可以正常工作了。此外,如果我删除 x 的内部定义并将 x 的值作为外部函数的参数(是否为负数),如

function t=test(x)
    function y=f()
        y=x;
    endfunction
    t=@f;
endfunction

然后评估例如test(-1)(3),也没有出现错误。这是错误还是误解了函数句柄或嵌套函数的工作方式?

Octave 文档建议使用子函数而不是嵌套函数,但它们无法访问其父函数的局部变量,我需要 returned 函数来依赖于函数的输入 return 正在处理它。有什么想法吗?

从 Octave 版本 5.2.0 开始,完全不支持嵌套函数句柄。我猜这是版本 6 的新颖之处。

八度函数不是变量,引擎在读取文件时compiles\translates它们。我的猜测是您观察到的行为会受到函数加载时当前工作空间的影响。

做你想做的事情的常用方法是生成匿名 (lambda) 函数:

function t = test1(x=-1)
    t = @()x;
end
function t = test2(x=-1)
    function s = calc(y,z)
        s = y + 2*z;
    end
    t = @(a=1)calc(a,x);
end

请注意,生成函数的默认参数应在 lambda 定义中说明。否则,如果你像 test2()() 这样调用它,它在调用 calc(a,x).

时将不知道将什么放入 a

如果您尝试创建闭包(具有关联状态的函数),Octave 的选项有限。在这种情况下,您可以查看 Octave 的 object oriented functionality. Classdef 可能对快速解决方案有用。

这是在此处跟踪的错误:

https://savannah.gnu.org/bugs/?func=detailitem&item_id=60137

看起来它已修复,将在下一个版本中消失。

另外,为了解释负数和正数的不同行为:我做了一些实验,没有捕获到分配了 computed 值的变量:

function t=tst()
  x = [5,3;0,0]; # captured
  y = [5,3;0,0+1]; # not captured
  z = x + 1; # not captured
  function y=f()
      
  endfunction
  t=@f;
endfunction
>> functions(tst)
ans =

  scalar structure containing the fields:

    function = f
    type = nested
    file =
    workspace =
    {
      [1,1] =

        scalar structure containing the fields:

          t = @f
          x =

             5   3
             0   0


    }

负数和正数的不同行为可能是由于数字被视为一元运算符 (uminus) 之前的减号 - 造成的。