如何在MATLAB匿名函数中执行多个语句?

时间:2009-02-17 19:59:03

标签: matlab command-line anonymous-function

我想做这样的事情:

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

所以当我说:

>> foo()

它会执行functionCall1()然后执行functionCall2()。 (我觉得我需要像C , operator

这样的东西

编辑:

functionCall1functionCall2不一定是返回值的函数。

6 个答案:

答案 0 :(得分:45)

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

首先,制作anonymous functions并将handles放入cell array

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

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

fcnArray = {@fcn1 @fcn2 @fcn3};

然后你可以创建一个新的匿名函数,使用内置函数cellfunfeval调用数组中的每个函数:

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


WORD OF WARNING: cellfun的文档说明计算输出元素的 order 未指定且不应依赖。这意味着无法保证在fcn1fcn2之前评估fcn3。如果订单很重要,则不应使用上述解决方案。

答案 1 :(得分:11)

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

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

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

有时你可以像gnovice的建议那样侥幸逃脱。

小心使用eval ...效率非常低(绕过JIT),Matlab的优化器可能会混淆eval表达式中使用的外部作用域的变量和函数。调试和/或扩展使用eval的代码也很困难。

答案 2 :(得分:6)

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

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版本,并根据需要混合和匹配它们。

答案 3 :(得分:1)

如果functionCall1()functionCall2()返回某些内容并且可以连接这些内容,那么您可以执行此操作:

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

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

这样做的副作用是foo()将返回functionCall1()functionCall2()返回的串联。

我不知道functionCall1()functionCall2()的执行顺序是否得到保证。

答案 4 :(得分:1)

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

curly = @(x, varargin) x{varargin{:}};
f=@(x)curly({exp(x),log(x)})
[a,b]=f(2)

答案 5 :(得分:0)

也许我错过了一些东西,只需要为你调用这两个函数的函数组合调用。