44

我想做这样的事情:

>> foo = @() functionCall1() functionCall2()

所以当我说:

>> foo()

它将执行functionCall1()然后执行functionCall2()。(我觉得我需要像C , operator之类的东西)

编辑:

functionCall1并且functionCall2不一定是返回值的函数。

4

5 回答 5

47

尝试通过命令行完成所有操作而不将函数保存在 m 文件中可能是一项复杂而混乱的工作,但这是我想出的一种方法......

首先,创建你的匿名函数并将它们的句柄放在一个单元格数组中:

fcn1 = @() ...;
fcn2 = @() ...;
fcn3 = @() ...;
fcnArray = {fcn1 fcn2 fcn3};

...或者,如果您已经定义了函数(例如在 m 文件中),请将函数句柄放在一个元胞数组中,如下所示:

fcnArray = {@fcn1 @fcn2 @fcn3};

然后,您可以创建一个新的匿名函数,该函数使用内置函数调用数组中的每个函数,cellfun并且feval

foo = @() cellfun(@feval,fcnArray);

虽然看起来很有趣,但它确实有效。

编辑:如果fcnArray需要使用输入参数调用函数,您首先必须确保数组中的所有函数都需要相同数量的输入。在这种情况下,以下示例显示如何调用具有一个输入参数的函数数组:

foo = @(x) cellfun(@feval,fcnArray,x);
inArgs = {1 'a' [1 2 3]};
foo(inArgs);  %# Passes 1 to fcn1, 'a' to fcn2, and [1 2 3] to fcn3


警告词:用于cellfun说明计算输出元素的顺序的文档未指定且不应依赖。这意味着不能保证在或fcn1之前得到评估。如果顺序很重要,则不应使用上述解决方案。fcn2fcn3

于 2009-02-17T21:49:09.340 回答
13

Matlab 中的匿名函数语法(像其他一些语言一样)只允许一个表达式。此外,它具有不同的变量绑定语义(不在参数列表中的变量在函数创建时具有词法绑定的,而不是绑定引用)。这种简单性允许 Mathworks 在幕后进行一些优化,并在脚本中使用它们时避免很多混乱的范围和对象生命周期问题。

如果您在函数(而不是脚本)中定义此匿名函数,则可以创建命名内部函数。内部函数具有正常的词法引用绑定并允许任意数量的语句。

function F = createfcn(a,...)
  F = @myfunc;
  function b = myfunc(...)
    a = a+1; 
    b = a; 
  end
end

有时你可以通过像 gnovice 的建议这样的技巧侥幸逃脱。

使用 eval 时要小心……它的效率非常低(它绕过了 JIT),而且 Matlab 的优化器可能会混淆在 eval 表达式内部使用的外部范围的变量和函数。也很难调试和/或扩展使用 eval 的代码。

于 2009-02-18T05:39:24.810 回答
7

这是一种保证执行顺序的方法,并且(在最后提到的修改)允许将不同的参数传递给不同的函数。

call1 = @(a,b) a();
call12 = @(a,b) call1(b,call1(a,b));

关键是call1调用它的第一个参数并忽略它的第二个参数。call12调用它的第一个参数,然后调用它的第二个,从第二个返回值。它之所以有效,是因为函数不能在其参数之前进行评估。要创建您的示例,您将编写:

foo = @() call12(functionCall1, functionCall2);

测试代码

这是我使用的测试代码:

>> print1=@()fprintf('1\n');
>> print2=@()fprintf('2\n');
>> call12(print1,print2)
1
2

调用更多函数

要调用 3 个函数,您可以编写

call1(print3, call1(print2, call1(print1,print2)));

4个功能:

call1(print4, call1(print3, call1(print2, call1(print1,print2))));

更多功能,继续嵌套模式。

传递参数

如果您需要传递参数,您可以编写一个带有call1参数的版本,然后对call12.

call1arg1 = @(a,arg_a,b) a(arg_a);
call12arg1 = @(a, arg_a, b, arg_b) call1arg1(b, arg_b, call1arg1(a, arg_a, b))

您还可以制作带有多个参数的 call1 版本,并根据需要混合和匹配它们。

于 2012-10-17T18:55:24.673 回答
3

可以使用用于创建逗号分隔列表的curly函数。

curly = @(x, varargin) x{varargin{:}};
f=@(x)curly({exp(x),log(x)})
[a,b]=f(2)
于 2016-01-14T18:00:57.707 回答
1

如果functionCall1()and functionCall2()return something 并且这些东西可以连接起来,那么你可以这样做:

>> foo = @() [functionCall1(), functionCall2()]

或者

>> foo = @() [functionCall1(); functionCall2()]

这样做的一个副作用是,foo()它将返回任何内容的串联functionCall1()functionCall2()返回。

不知道functionCall1()and的执行顺序functionCall2()是否有保证。

于 2009-02-18T12:30:29.690 回答