MATLAB:varargin 与 'real' 元胞数组的行为不同?

MATLAB: varargin acting differently from 'real' cell array?

varargin 与元胞数组完全一样吗?

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

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

当我用子 class

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

用解析器调用 superclass 的构造函数,然后 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

它按预期工作。

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

为简化起见,我在解释问题时会忘记所有 class 内容。你有一个函数 foo(varargin)bar(varargin)

如果您现在调用 foo(1,2,3),它会被调用 varargin={1,2,3}。如果你现在想在 foo 中调用 bar(1,2,3),你不能简单地使用 bar(varargin),那就是 bar({1,2,3})。相反,您必须使用逗号分隔列表调用 barbar(varargin{:})。这会将元胞数组的元素解压缩为 1,2,3,从而产生您想要的调用。

在您的代码中它将是:

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