MATLAB:varargin的行为不同于真实的'细胞阵列?

时间:2016-03-07 12:51:06

标签: matlab variadic-functions

varargin与单元格数组完全相同吗?

我的测试类中有一个简单的varargin解析器,如下所示:

classdef MySuperClass
properties(Access = protected)
    superPropA = (1:4);
    superPropB = 'superBar';
end

methods
    % constructor
    function obj = MySuperClass(varargin)
        % check varargins

        % required parameter
        arg = varargin(find(strcmp(varargin, 'SuperA'))+1);
        if ~isempty(arg) && isnumeric(arg{1}) && length(arg{1}) > 1
            obj.superPropA = arg{1};
        else
            newExc = MException('SubClass:Constructor:InputParser',...
                'Expected numeric vector argument for SuperA');
            throw(newExc);
        end

        % optional parameter
        if any(strcmp(varargin, 'SuperB'))
            arg = varargin(find(strcmp(varargin, 'SuperB'))+1);
            if ~isempty(arg)
                obj.superPropB = arg{1};
            else
                newExc = MException('SubClass:Constructor:InputParser',...
                    'Expected argument for SuperB');
                throw(newExc);
            end
        end

        % output varargins
        fprintf('SuperClass:\nSuper property A: %s\nSuper property B: %s', obj.superPropA, obj.superPropB);
    end
end
end

当我从我的子类

中实例化SubInst = MySubClass('SuperA', (1:5), 'SuperB', 'Hello')的类时
function obj = MySubClass(varargin)
            % call super class constructor
            obj = obj@SuperClassModules.MySuperClass(varargin);
...

用解析器调用超类的构造函数,然后arg是{}(参见第一个代码块),它不应该来自我的理解。

因为当我输入控制台时:

>> a = {'SuperA', (1:5), 'SuperB', 'Hello'}

a = 

    'SuperA'    [1x5 double]    'SuperB'    'Hello'

>> arg = a(find(strcmp(a, 'SuperA'))+1)

arg = 

    [1x5 double]

>> arg{1}

ans =

     1     2     3     4     5

它按预期工作。

为什么它在构造函数中不起作用?

1 个答案:

答案 0 :(得分:3)

为了简化,我在解释问题时会忘记所有类的东西。您有一个功能foo(varargin)bar(varargin)

如果您现在致电foo(1,2,3),则可以使用varargin={1,2,3}进行呼叫。如果您现在想要在bar(1,2,3)内拨打foo,则无法使用bar(varargin),即bar({1,2,3})。相反,您必须使用逗号分隔列表bar来呼叫bar(varargin{:})。这会将单元格数组的元素解压缩到1,2,3,从而产生您想要的调用。

在您的代码中,它将是:

obj = obj@SuperClassModules.MySuperClass(varargin{:});