我有一个函数,我希望通过varargin
传递参数,并使用inputParser
来确保输入是正确的。有些论据是必需的,有些则不是。这是一个例子:
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
的元素并踢出参数名称,但这并不是非常优雅。
答案 0 :(得分:7)
我能想到的最优雅的解决方案是继承inputParser
。所以你可以这样做(另存为myInputParser.m):
classdef myInputParser < inputParser
properties
required = {};
end
methods
function obj = myInputParser
obj = obj@inputParser;
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
parse@inputParser(obj, varargin{:});
end
end
end
然后改变
p = inputParser;
到
p = myInputParser;
然后您的代码将按您的意愿运行。
请注意,这可能无法正确处理所有边缘情况,并且我没有对它进行过广泛的测试,但它确实适用于您的示例用例。
答案 1 :(得分:5)
在InputParser中,您只能将{em> ParameterName - ParameterValue 对添加到addParamValue
。这些论点应该是可选的。
作为一种变通方法,您可以使用addParamValue
添加所有参数,并使用[]
作为必需参数的默认值。
然后您可以执行以下操作之一:
validateattributes
函数中的属性添加'非空'以获取所需的参数(但是在这种情况下,错误消息不会说这是必需的参数,但它必须是非空的)if
或assert
)所需的参数不应为空,并带有您自己的错误消息。您不仅限于使用[]
。默认值可以是任何不适合特定参数的值,并且易于检查。