'too many output arguments' 在 Matlab 中将函数传递给另一个函数时出错

'too many output arguments' error when passing function to another function in Matlab

我有一些错误处理代码,我想要一堆函数使用,所以为了避免重复,我想我会把它放在我的泛型 class 中,它包含实用函数 FunctionContainer .

这是 FunctionContainer 的截断版本:

classdef FunctionContainer
methods (Static)
    
    function run(func, ExpInfo, logdir, newdir, varargin)
        try 
            func(ExpInfo, newdir, varargin)
        catch ME
            FunctionContainer.errproc(logdir, newdir, ME)
        end
    end
    
    function errproc(logdir, newLogDir, ME) 
        errdir = fullfile(logdir, 'error');
        movefile(newLogDir, errdir);
        pathParts = strsplit(newLogDir, filesep);
        logID = pathParts(end);
        newLogText = fullfile(errdir, logID, 'error.txt');
        fid = fopen(newLogText, 'wt');
        fprintf(fid, '%s\n%s\n', ME.identifier, ME.message);
        for i = 1:length(ME.stack)
            fprintf(fid, '%i\t%s\n', ME.stack(i).line, ...
                ME.stack(i).file);
        end
        fclose(fid);
        rethrow(ME);
    end
  
    function newdir = prolog(logdir, id, supfiles)
        id = join([id, string(clock)], '_');
        newdir = fullfile(logdir, id); mkdir(newdir)
        stack = dbstack('-completenames');
        files = horzcat({stack.file}, supfiles);
        for i = 1:numel(files)
            copyfile(files{i}, newdir)
        end    
    end
end

结束

这是我使用它的上下文:

function realign(ExpInfo)

    fc = FunctionContainer;
    logdir = ExpInfo.logdir;
    ws = fullfile(logdir, 'workspace.mat'); save(ws);
    newdir = fc.prolog(logdir, 'realign', {ws});

    fc.run(runRealign, ExpInfo, logdir, newdir);

    function runRealign(ExpInfo, newdir)
         % do a bunch of stuff
    end
end

我的脚本 ks_main.m 中调用 realign 的相关行是

realign(FullData)

我收到这个错误:

8   fc.run(runRealign, ExpInfo, logdir, newdir);
Error using realign/runRealign
Too many output arguments.

Error in realign (line 8)
fc.run(runRealign, ExpInfo, logdir, newdir);

Error in ks_main (line 35)
realign(FullData)

在这种情况下,我只是不明白这个错误。 None 这些函数正在返回任何内容或有任何输出。我也许可以理解 runRealign 是否获得了太多输入,并且我尝试像这样定义 runRealign

function runRealign(ExpInfo, newdir, varargin)

但这没有什么区别。也许这与将函数作为参数传递给另一个函数有关?在 Matlab 中执行此操作的正确方法是什么?

您需要在 fc.run 中的函数参数前放置 @ 符号。将函数句柄作为参数 (https://au.mathworks.com/help/matlab/matlab_prog/pass-a-function-to-another-function.html) 传递时始终执行此操作。 realing.m 的第 8 行应该是:

fc.run(@runRealign, ExpInfo, logdir, newdir);

还有其他几个问题。一是您在 FunctionContainer 末尾缺少 end。这可能只是您问题中的错字,否则您也会遇到与此相关的错误。

另一个小的实现细节是,如果它无论如何都将成为 ExpInfo 中的一个字段,则不需要使用 logdir 作为参数——您可以简单地从ExpInfoFunctionContainer 内部,而不必将其显式传递给 run。将 ExpInfo 及其字段 logdir 传递给同一个函数是不明确的,在风格上是不好的做法。 (这提醒了我,你也应该在你的问题中提供 FullData 的定义。我不得不辨别它需要这个字段。)

然而,这段代码也会导致在 FunctionContainer 的第 6 行抛出异常。 runRealign 的定义只需要 2 个参数,但是当你 try 到 运行 它在 FunctionContainer 你期望 3: func(ExpInfo, newdir, varargin)。如果我将 FunctionContainer 的第 6 行更改为:

func(ExpInfo, newdir)

有效。

为了使这个健壮且无错误,您需要解析 FunctionContainer 中的 varargin 以便它智能地处理可变数量的参数 (https://au.mathworks.com/help/matlab/ref/varargin.html),或者保证输入函数句柄指向一个永远有 2 个参数的句柄。