'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
作为参数——您可以简单地从ExpInfo
在 FunctionContainer
内部,而不必将其显式传递给 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 个参数的句柄。
我有一些错误处理代码,我想要一堆函数使用,所以为了避免重复,我想我会把它放在我的泛型 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
作为参数——您可以简单地从ExpInfo
在 FunctionContainer
内部,而不必将其显式传递给 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 个参数的句柄。