首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MATLAB:将inputParser与varargin结合使用

MATLAB:将inputParser与varargin结合使用
EN

Stack Overflow用户
提问于 2012-02-10 09:53:09
回答 2查看 7.1K关注 0票数 4

我有一个函数,我希望通过varargin传递它的参数,并使用inputParser来确保输入是合理的。有些参数是必需的,有些则不是。下面是一个示例:

代码语言:javascript
运行
复制
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

我希望能够像下面这样传递参数;无论何时传入哪一对都无关紧要,只要需要的参数就在那里。因此,示例调用可能是:

代码语言:javascript
运行
复制
myFunc('numStates', 4, 'numInps', 2, 'numOUts', 3, 'X0', [4;0]);

显然,这种语法是非法的;parse()要求其中的第一个参数是所需的值,但它们不应该显式命名,即如下所示:

代码语言:javascript
运行
复制
function myFunc(numStates, numInps, numOuts, X0, varargin)
    ...
    p.parse(numStates, numInps, numOuts, X0, varargin{:});

end

有没有一种简单的方法可以让它做我想要的,也就是第一个函数?我想最简单的方法就是重新排序varargin的元素,去掉参数名,但这并不是很优雅。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-10 13:02:01

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

代码语言:javascript
运行
复制
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

然后改变

代码语言:javascript
运行
复制
    p = inputParser;

代码语言:javascript
运行
复制
    p = myInputParser;

然后你的代码就会像你想要的那样工作。

请注意,这可能不能正确处理所有边缘情况,我也没有对它进行广泛的测试,但它确实适用于您的示例用例。

票数 7
EN

Stack Overflow用户

发布于 2012-02-10 12:22:21

在InputParser中,您只能使用addParamValue添加ParameterName - ParameterValue对。这些参数应该是可选的。

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

然后您可以执行以下操作之一:

  • 将'nonempty‘添加到validateattributes函数中所需参数的属性中(但在这种情况下,错误消息不会指出这是必需参数,但必须为非空)
  • 或添加单独的检查(使用ifassert),检查所需参数不应为空,并显示您自己的错误消息。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9221690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档