问题描述
这个函数应该是返回一个函数句柄给内部嵌套函数,但是如果变量x在外层函数中设置为负值,则不起作用。
内部嵌套函数只是一个常量函数,返回在外部函数中设置的变量 x 的值。
function t=test(x)
x=-1;
function y=f()
y=x;
endfunction
t=@f;
endfunction
如果我尝试评估返回的函数,例如test()(3)
,我收到一个关于 x 未定义的错误。如果 x 被定义为具有至少一个负项的向量,或者如果 x 是函数的参数并且使用负默认值进行评估,则会发生同样的情况。但是如果我改为将其定义为某个非负值
function t=test(x)
x=1;
function y=f()
y=x;
endfunction
t=@f;
endfunction,
然后返回的函数工作得很好。此外,如果我删除 x 的内部定义并将 x 的值作为外部函数的参数(负或非),如
function t=test(x)
function y=f()
y=x;
endfunction
t=@f;
endfunction
然后评估例如test(-1)(3)
,错误也不会发生。这是错误还是我误解了函数句柄或嵌套函数的工作原理?
Octave 文档建议使用子函数而不是嵌套函数,但它们无法访问其父函数的局部变量,我需要返回的函数依赖于返回它的函数的输入。任何想法如何解决这个问题?
解决方法
这是在此处跟踪的错误:
https://savannah.gnu.org/bugs/?func=detailitem&item_id=60137
看起来它已修复,将在下一个版本中消失。
另外,为了解释负数和正数的不同行为:我进行了一些实验,并没有捕获分配了计算值的变量:
function t=tst()
x = [5,3;0,0]; # captured
y = [5,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
引起的。
从 Octave 版本 5.2.0
开始,根本不支持嵌套函数句柄。我猜这是第 6 版的新奇之处。
在八度函数中,函数不是变量,引擎在读取文件时编译\翻译它们。我的猜测是,您观察到的行为会受到函数加载时当前工作区的影响。
执行您尝试执行的操作的常用方法是生成匿名 (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()()
一样调用它,它在调用 a
时将不知道该将什么放入 calc(a,x)
。
如果您正在尝试创建一个闭包(具有关联状态的函数),octave 对此的选择有限。在这种情况下,您可以查看 Octave 的 object oriented 功能。 Classdef 可能对快速解决方案很有用。