MATLAB:使用inputParser与varargin

问题描述:

我有一个函数,我想通过varargin传递参数,并使用inputParser来确保输入是合理的。有些论据是必需的,有些则不是。这里是一个例子:MATLAB:使用inputParser与varargin

function myFunc(varargin) 
    p = inputParser; 
    p.addRequired(... 
      'numStates', ... 
       @(x) validateattributes(x, {'numeric'}, ... 
       {'scalar', 'integer', 'positive'})); 
     p.addRequired(... 
      'numInps', ... 
       @(x) validateattributes(x, {'numeric'}, ... 
       {'scalar', 'integer', 'positive'})); 
     p.addRequired(... 
      'numOuts', ... 
       @(x) validateattributes(x, {'numeric'}, ... 
       {'scalar', 'integer', 'positive'})); 
     p.addRequired(... 
      'X0', ... 
       @(x) validateattributes(x, {'numeric'}, ... 
       {'vector'})); 
     p.addOptional(... 
      'freq', 10, ... 
       @(x) validateattributes(x, {'numeric'}, ... 
       {'scalar', 'integer', 'positive'})); 
     p.addOptional(... 
      'SimulinkVariables', struct(), ... 
       @(x) isa(x, 'struct')); 

    p.parse(varargin{:}); 

    %# do stuff with variables 
end 

我想能够通过参数如下;只要所需的那一对在那里,哪一对都可以通过。因此,示例调用可能是:

myFunc('numStates', 4, 'numInps', 2, 'numOUts', 3, 'X0', [4;0]); 

显然,该语法是非法的; parse()预计,它的第一个参数是必需的价值观,但他们不应该被明确命名,即,如:

function myFunc(numStates, numInps, numOuts, X0, varargin) 
    ... 
    p.parse(numStates, numInps, numOuts, X0, varargin{:}); 

end 

有一个简单的方法,使这个做我想做的,即第一功能?我想最简单的做法是做一些事情来重新排序varargin的元素,并剔除参数名称,但这不是非常优雅。

+1

您正在使用inputParser错误。请参阅@ yuk的答案。 – Nzbuu 2012-02-16 13:36:08

我能想到的最优雅的解决方案是子类inputParser。所以,你可以做这样的事情(保存为myInputParser.m):

classdef myInputParser < inputParser 
    properties 
     required = {}; 
    end 

    methods 
     function obj = myInputParser 
      obj = [email protected]; 
     end 

     function addRequired(obj, argname, validator) 
      obj.required = {obj.required{:}, argname}; 
      obj.addOptional(argname, [], validator); 
     end 

     function parse(obj, varargin) 
      params_input = varargin(1:2:end); 
      for i=1:length(obj.required) 
       if isempty(strmatch(obj.required{i}, params_input)) 
        error(sprintf('Required named parameter %s was not passed to function', obj.required{i})); 
       end 
      end 
      [email protected](obj, varargin{:}); 
     end 

    end 
end 

然后改变

p = inputParser; 

p = myInputParser; 

,然后你的代码将作为你想让它。

请注意,这可能无法正确处理所有边界情况,并且我没有对其进行广泛的测试,但它可以用于您的示例用例。

+0

确实很高雅!非常感谢。 – 2012-02-10 06:14:20

在InputParser中,您可以添加ParameterName - ParameterValue仅与addParamValue配对。这些论据应该是可选的。

作为解决方法,您可以使用addParamValue添加所有参数,并使用[]作为所需参数的默认值。

然后,你可以做下列操作之一:

  • 附加“非空”,以属性在validateattributes功能所需的参数(然而,在这种情况下,该错误信息不会说这是必需的参数,但它必须是非空的
  • 或添加单独的检查(与ifassert),需要参数应该不是空的与您自己的错误消息。

您不限于使用[]。默认值可以是任何不适用于特定参数的值,并且易于检查。