【问题标题】:Why is this function handle being used in the incorrect context?为什么在不正确的上下文中使用此函数句柄?
【发布时间】:2015-08-20 23:24:42
【问题描述】:

我试图了解如何将函数传递给varfun,我想这适用于arrayfuncellfun 等。

读取帮助文件,第一个参数应该是:

函数,指定为函数句柄。您可以在文件中定义函数或将其定义为匿名函数。如果 func 对应多个函数文件(即,如果 func 表示一组重载函数),MATLAB 会根据输入参数的类确定调用哪个函数。

所以我尝试使用以下数据:

sampleId = [1 1 1 3 3 3]';
entity = [1 2 3 1 4 5]';
dataTable = table(sampleId, entity)

是的:

varfun(@mean, dataTable)

ans = 

    mean_sampleId    mean_entity
    _____________    ___________

    2                2.6667     

现在,当我匿名定义自己的函数时,就会出现问题,例如:

mymean = @(x){sum(x)/length(x)};

然后抛出错误

varfun(@mymean, dataTable)
Error: "mymean" was previously used as a variable, conflicting with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB documentation for details.

然而,如果我不使用 at 符号,我会得到:

varfun(mymean, dataTable)

ans = 

    Fun_sampleId    Fun_entity
    ____________    __________

    [2]             [2.6667]  

我觉得我一定是在错误的上下文中使用了函数句柄@。任何人都可以启发我吗? (注意,如 cmets 中所述,ans 的显示很奇怪,因为 mymean 返回一个元胞数组。这是一个意外错误。

【问题讨论】:

    标签: arrays matlab function anonymous-function


    【解决方案1】:

    在第一个代码 sn-p 中,mean(named) function@mean 是该函数的 function handle。您可以等效地使用

    f = @mean;
    varfun(f, dataTable)
    

    在第二种情况下,当你定义

    mymean = @(x){sum(x)/length(x)};
    

    @(x){sum(x)/length(x)}part 是 anonymous function,而变量 mymean 又是该(匿名)函数的 函数句柄。所以你需要使用varfun(mymean, dataTable),而不是varfun(@mymean, dataTable)

    所以,@ 符号正在使用 in two different ways,尽管在这两种情况下它都会产生一个函数句柄:

    • 案例 1:从命名函数创建函数句柄。命名函数是在自己的文件中定义的函数。
    • 案例 2:作为匿名函数定义的一部分。匿名函数是直接定义的,而不是在单独的文件中。该定义构造了一个匿名函数并自动返回该函数的句柄。

    【讨论】:

    • @AndrasDeak 不确定您指的是我的哪个 cmets。如果您想知道为什么 mymean 返回一个元胞数组,那只是一个错字。如果你想知道我为什么要将mymean 放到一个单独的文件中以便我可以通过函数句柄调用它,那是因为我使用eval 来构造对varfun 的调用,所以符号必须保持一致
    • @Alex,我的意思是后者,坚持使用@。那么,eval 是不可避免的吗? (我想是的,我假设你也只在你真的需要时才使用它。)但这对于你的问题可能太离题了......
    • 是的,也许这是一个单独讨论的主题,但这就是我使用eval 的原因。我的函数fn(function_name) 需要一个函数名作为它的参数,然后我通过调用func = eval(['@' func]) 构造一个句柄。我想现在你告诉我要避免它,我可以直接在fn 中传递函数句柄?
    • @Alex 从您的代码看来,func 最初是一个字符串。在这种情况下,使用str2func(func) 来获取函数的句柄,该函数的名称包含在该字符串中
    • @Alex,还请注意,Luis 提出的替代方案也将平等对待命名函数和匿名函数(这让我很难过我不能投票),结果将始终是可以传递给varfun的函数句柄。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2010-10-22
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多