我尝试在 Matlab 脚本中编写递归内联匿名函数。
这里是一个 MWE:
funR = @(x) [x(1) funR(x(2:end))];
funR(0:5);
但这会引发以下异常:
Undefined function or variable 'funR'.
这在函数文件中运行时有效,但在脚本中运行时无效。这是因为 Matlab 读取它们的方式不同。
我对这个 MWE 的预期结果是:
[0, 1, 2, 3, 4, 5]
如何正确地做到这一点?
目标是将 funR 定义为内联函数,因此两行或更多行的解决方案不是我想要的。如果这个或 MWE 有意义,请忽略,这不是这个问题的重点。
您不能这样做,因为匿名函数内部使用的函数和变量必须在创建时而不是执行时定义,并且匿名函数本身直到赋值后才定义。
编写递归匿名函数的正确方法是为匿名函数提供第二个输入,即匿名函数本身,以便匿名函数可以使用该函数句柄调用自身。
funR = @(x, funR) [x(1) funR(x(2:end), funR)];
funR(0:5, funR)
这对您不起作用,因为您需要在某个时候停止迭代。有一个 great series of articles on functional programming with anonymous functions由 Loren 在 Mathworks 撰写,涵盖了这一点。借用那篇文章,我们可以使用 iif
匿名函数让我们的匿名函数在到达数组末尾时正确终止。
% From the article linked above
iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
% Recurse as long as there is more than one element in x
funR = @(x,funR)iif(numel(x) > 1, @()[x(1), funR(x(2:end), funR)], ...
true, x);
funR(0:5, funR)
除此之外,从性能的角度来看,这可能会产生糟糕的结果。可能有一种不需要递归匿名函数的矢量化方法来解决这个问题。