Mentre le soluzioni con nargin
sono già fornite e più o meno un uso standard all'interno della maggior parte delle basi di codici MATLAB, penso che ci sia un'alternativa migliore che sia più leggibile.
Con nargin
in grandi funzioni, è necessario ricordare quale argomento 3 era esattamente. Soprattutto se si hanno più argomenti opzionali, diventa difficile tenere traccia o consentire che vengano passati alcuni argomenti facoltativi, mentre altri no.
Il primo e più semplice soluzione è la mia alternativa personale a nargin
, e che sta usando la funzione exist
:
function [output] = getValue(modelName,param,option, otherOption)
if ~exist('option', 'var') || isempty(option)
option = 'defaultValueForOption';
end
if ~exist('otherOption', 'var') || isempty(otherOption)
otherOption = 'defaultValueForOption';
end
% perform other actions
Il vantaggio è che ora tutto il codice di ingresso relativo è all'inizio ed è più verboso quanto a cosa dovrebbe accadere. Non ingombrerai il tuo altro codice con quella logica. Inoltre, è possibile integrare le istruzioni if
con la convalida dell'input e tornare all'impostazione predefinita quando viene fornita un'opzione non valida.
L'altra possibilità è standard nelle versioni successive di MATLAB: la classe inputParser
. Con questa classe, è possibile definire scenari ancora più complicati di parametri opzionali e persino coppie chiave-valore.
Di seguito è riportato un esempio auto-descrittivo che ho mantenuto per evitare di aver bisogno della documentazione ogni volta. Non
%% Usage Example input Parser
%
function output = FuncName(rParam1, rParam2, oParam1, oParam2, varargin)
p = inputParser();
defaultValue = 0;
validatorFunc = @(x)(true); % validator function should return true when x is valid
%% Input Format definition
p.addRequired('rParam1', validatorFunc);
p.addRequired('rParam2', validatorFunc);
p.addOptional('oParam1', defaultValue, validatorFunc);
p.addOptional('oParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam1', defaultValue, validatorFunc);
p.addParamValue('kvParam2', defaultValue, validatorFunc);
p.addParamValue('kvParam3', defaultValue, validatorFunc);
p.addParamValue('kvParam4', defaultValue, validatorFunc)
%% Optional Settings
% expand supplied struct to ParamValue pairs (or other arguments)
p.StructExpand = true; % default: false
%% Parse
p.parse(rParam1, rParam2, oParam1, oParam2, varargin{:})
%% Retrieve results
values = p.Results(); % structure with all values
defaultedArgs = p.UsingDefaults; % cell array of all parameter names using defaults
end
Questo approccio è ancora più prolisso e personalmente, faccio piace molto il fatto che si deve ridefinire per ogni ingresso se è obbligatorio o facoltativo e che richiede un bel po 'di codice standard. Ma almeno, è una soluzione che è una soluzione standard e senza dubbio da preferire per le funzioni più grandi.
Entrambi gli approcci presentano uno svantaggio rispetto al metodo di controllo nargin
: entrambi sono più lenti. Quindi, se si utilizzano queste funzioni in chiamate molto numerose (o si esegue solo un calcolo molto rapido), potrebbe essere più utile utilizzare nargin
.
Cosa ti aspetteresti che 'runModel' faccia se non passi il parametro' option'? –
Vorrei chiamare: getValue (modelName, param) da altri file – lola