嵌套函数的函数句柄不适用于某些参数值
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
) 之前的减号 -
造成的。
这个函数本应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
) 之前的减号 -
造成的。