How to deal with name/value pairs of function arguments in MATLAB

后端 未结 14 1099
忘掉有多难
忘掉有多难 2020-11-28 19:28

I have a function that takes optional arguments as name/value pairs.

function example(varargin)
% Lots of set up stuff
vargs = varargin;
nargs = length(vargs         


        
14条回答
  •  盖世英雄少女心
    2020-11-28 19:45

    I ended up writing this today, and then found these mentions. Mine uses struct's and struct 'overlays' for options. It essentially mirrors the functionality of setstructfields() except that new parameters can not be added. It also has an option for recursing, whereas setstructfields() does it automatically. It can take in a cell array of paired values by calling struct(args{:}).

    % Overlay default fields with input fields
    % Good for option management
    % Arguments
    %   $opts - Default options
    %   $optsIn - Input options
    %       Can be struct(), cell of {name, value, ...}, or empty []
    %   $recurseStructs - Applies optOverlay to any existing structs, given new
    %   value is a struct too and both are 1x1 structs
    % Output
    %   $opts - Outputs with optsIn values overlayed
    function [opts] = optOverlay(opts, optsIn, recurseStructs)
        if nargin < 3
            recurseStructs = false;
        end
        isValid = @(o) isstruct(o) && length(o) == 1;
        assert(isValid(opts), 'Existing options cannot be cell array');
        assert(isValid(optsIn), 'Input options cannot be cell array');
        if ~isempty(optsIn)
            if iscell(optsIn)
                optsIn = struct(optsIn{:});
            end
            assert(isstruct(optsIn));
            fields = fieldnames(optsIn);
            for i = 1:length(fields)
                field = fields{i};
                assert(isfield(opts, field), 'Field does not exist: %s', field);
                newValue = optsIn.(field);
                % Apply recursion
                if recurseStructs
                    curValue = opts.(field);
                    % Both values must be proper option structs
                    if isValid(curValue) && isValid(newValue) 
                        newValue = optOverlay(curValue, newValue, true);
                    end
                end
                opts.(field) = newValue;
            end
        end
    end
    

    I'd say that using the naming convention 'defaults' and 'new' would probably be better :P

提交回复
热议问题