【问题标题】:Handling variadic arguments function calls in Matlab在 Matlab 中处理可变参数函数调用
【发布时间】:2012-01-12 13:53:59
【问题描述】:

我制作了一些辅助函数,它们使用其中的许多函数来运行模拟。

为了使这些辅助函数对用户更加友好,我想让用户选择使用更少的参数调用函数(未传递给函数的参数被分配一个预定义的值)。

例如,如果我有一个函数

function [res, val, h, v, u] = compute(arg1, arg2, arg3, arg4)
    if nargin < 4 || isempty(arg4) arg4 = 150; end

和这样定义的函数runsim

function [res, val, h, v, u] = runsim(v, arg1, arg2, arg3, arg4)

愚蠢的做法是

if nargin < 5 || isempty(arg4)
    compute(arg1, arg2, arg3)
else
    compute(arg1, arg2, arg3, arg4)
end

另一种解决方案是将参数更改为向量,但不允许我触摸模拟背后的功能。是否有 Matlab 方法来处理这种情况,还是我必须用更少的参数一次又一次地编写相同的代码?

【问题讨论】:

  • 你的意思是不能改变“compute”?
  • @Andrey 是的,我就是这个意思。

标签: matlab variadic-functions


【解决方案1】:

您可以使用元胞数组打包和解包函数参数:

a={'foo','bar',42}
fun(a{:}) % is the same as:
fun('foo','bar',42)

输出参数也是如此:

a,b,c=fun(); % or easier:
c=cell(3,1);
[c{:}]=fun();

由于 varargin 也是一个元胞数组,您只需弹出要执行的函数所在的字段,然后将其余字段作为参数传递给函数。

【讨论】:

  • 我喜欢它并且它有效。现在我只是添加或删除参数,我只做一次调用。
【解决方案2】:

我倾向于同意@Chris,但我想介绍一些细微的变化。
如果您的意思是您无法更改 compute(),那么您可以使用 vararginName/Value 成语。

(为了运行这段代码,你必须从Matlab central下载catstruct()函数)

function runsim( varargin) 
      partialParams= struct(varargin{:});
      % Check each variable 
      DefaultVal1 = 1;
      DefaultVal2 = 2;
      defaultParams = struct('Param1',DefaultVal1,'Param2',DefaultVal2');
      % Merge 2 structs
      params = catstruct(defaultParams,partialParams);
      % Call compute on the parameters.
      fnames = fieldnames(params);
      vals = {};
      for i=1:numel(fnames)
            vals{end+1} = params.(fnames{i});
      end
      compute( vals{:});
 end

以及调用函数:

 runsim('Param1',Value1,'Param2',Value2);
 runsim('Param2',Value2);
 runsim('Param1',Value1);

【讨论】:

    【解决方案3】:

    通常的方法是使用varagin。例如,要定义一个接受一个必需参数和四个可选参数的函数,我们可以这样做

    function [res, val, h, v, u] = runsim(v, varagin)
    
        % Check that at least 1 and at most 5 input arguments were passed
        error(nargchk(1, 5, nargin))
    
        % Check number of optional arguments passed
        noptargin = size(varargin, 2)
    
        % Check how many arguments passed, set default values if required.
        % Im sure the following could be cleaned up.
        if noptargin == 1
            arg1 = varagin{1}
            arg2 = ...
            arg3 = ...
            arg4 = ...
        elseif noptargin == 2
            arg1 = varagin{1}
            arg2 = varagin{2}
            arg3 = ...
            arg4 = ...
        elseif noptargin == 3
            arg1 = varagin{1}
            arg2 = varagin{2}
            arg3 = varagin{3}
            arg4 = ...
        end
    
        % Finally, call compute with all arguments set
        compute(arg1, arg2, arg3, arg4)
    
    end
    

    编辑:另一种方法是在 runsim 函数中使用 inputParser

    【讨论】:

      猜你喜欢
      • 2011-01-26
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 2013-03-14
      • 2021-01-17
      相关资源
      最近更新 更多