how to pass keyword arguments to a function via a struct

70 vues (au cours des 30 derniers jours)
Stephen Vavasis
Stephen Vavasis le 16 Jan 2023
In recent versions of Matlab, functions can declare optional arguments with default values that get automatically packed into a struct e.g.,
function examplefn(x)
arguments
x.a (1,1) double = 12
x.b (1,1) double = 7
end
With such a declaration, the function is called via examplefn('a', 8, 'b', 9) (or just examplefn('a',8)), and the examplefn function body can now use x.a and x.b as variables. Suppose I have written such a function, and its caller (rather than the function) has the arguments in a struct:
y = struct('a', 8, ,'b', 9);
What is the way to pass y as an input argument to examplefn? I'd like to be able to say something like: examplefn(unpack(y)). Obviously, I could spell it out: examplefn('a', y.a, 'b', y.b) but expanding in this way partly defeats the purpose of having optional and keyword arguments in the first place and makes it fragile to chain a sequence of functions that share keyword/optional arguments. Thanks.
  2 commentaires
dpb
dpb le 16 Jan 2023
At this time there is no syntax to do anything other than pass the name-value parameter pairs explicitly.
I didn't 'spearmint; you might be able to write an anonymous function that would do the unwrapping to the string to pass, but then you would have to revert to eval to execute the result; MATLAB wouldn't know what to do with the string as an argument list.
Stephen Vavasis
Stephen Vavasis le 16 Jan 2023
Déplacé(e) : Matt J le 16 Jan 2023
Thanks for all the responses! it seems that there are two possible solutions. The first is to use inputParser in examplefn instead of a function argument block. The second is to convert the struct to a cell array, and then use {:} on that array, which converts the cell array into multiple arguments.
Regarding the second approach, I can write an unpack function as follows:
function c1 = unpack(s)
arguments
s (1,1) struct
end
fieldn = fieldnames(s);
fieldv = struct2cell(s);
nfield = length(fieldn);
c1 = cell(2*nfield,1);
c1(1:2:end) = fieldn;
c1(2:2:end) = fieldv;
end
Then I can invoke examplefn via:
unpack_y = unpack(y);
examplefn(unpack_y{:})

Connectez-vous pour commenter.

Réponse acceptée

Walter Roberson
Walter Roberson le 16 Jan 2023

Plus de réponses (2)

Matt J
Matt J le 16 Jan 2023
Modifié(e) : Matt J le 16 Jan 2023
You'll have to go old school and use inputParser.
y = struct('a',8,'b', 9);
x=examplefn(y)
x = struct with fields:
a: 8 b: 9 c: 100
x=examplefn('a',8,'b',9)
x = struct with fields:
a: 8 b: 9 c: 100
function x=examplefn(varargin)
p=inputParser();
addParameter(p,'a',12);
addParameter(p,'b',7);
addParameter(p,'c',100);
parse(p,varargin{:});
x=p.Results;
end

Matt J
Matt J le 16 Jan 2023
Déplacé(e) : Walter Roberson le 16 Jan 2023
@Stephen Vavasis. Your unpack function is already available in Matlab as namedargs2cell.
  1 commentaire
Stephen Vavasis
Stephen Vavasis le 16 Jan 2023
Déplacé(e) : Walter Roberson le 16 Jan 2023
Great! I will use nameargs2cell, thanks!

Connectez-vous pour commenter.

Catégories

En savoir plus sur Interactive Control and Callbacks dans Help Center et File Exchange

Produits


Version

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by