Arguments accept char, string or "cellstr" (cell array of char or string)
66 次查看(过去 30 天)
显示 更早的评论
I have a large number of functions I eventually intend to be redistributable at my company. I had started creating my own variable validation routines but, fortunately I found the built in arguments block before I got too far down that road. It's very useful in data validation.
It's nice that arguments will allow not just strictly the given type/class of variable but will also allow anything that is convertible to that type (e.g. you can pass a string to char or char to string and any numeric types are also automatically converted). If you have two different types, it's a little trickier, but I've figured out how to use mustBeA and an array of strings of the types I want to accept.
One thing haven't figured out how to do effectively using this method. I have multiple aguments in multiple functions that can accept an input that is a char array, a string, or a cell array of char or string. I can use mustBeA to accept char, string, or cell - but I don't want to accept just any cell variable, it needs to be a cell array of char or string only, and it's not directly convertible. I know some MATLAB functions have sort of defined a type called cellstr which is a cell array of char or string - but that doesn't appear to be a checkable type in the arguments block.
I can, of course, add a block in my actual code to see if the argument matches iscell and then loop through the array and check all the elements but it would be nice if there's a way to do it within the arguments block.
Is there a way to do this inside the arguments block?
0 个评论
回答(3 个)
dpb
2023-2-8
You write a custom validation function that your code in the arguments block calls for special cases if you're using the supplied arguments checking routines.
I've not really adopted it as don't write "production" MATLAB code for others to use, but my "trick" for the specific case you've outlined above looks like
function res=myfunction(arg)
argOK=true;
try
cellstr(arg); % throws error if any cell content isn't char or string
catch
argOK=false;
... % do whatever need here -- throw error, fixup if can, whatever...
end
...
The less tricky, more straightforward way would be to use something like
isOK=all(cellfun(@(c)ischar(c)|isstring(c),arg),'all');
in the custom arg test function.
4 个评论
Matt Cooper
2023-3-7
编辑:Matt Cooper
2023-3-7
The cellfun method should also check for cell arrays of cells containing text:
tf = all(cellfun(@(x)ischar(x)|isstring(x)|iscellstr(x),x),'all');
Les Beckham
2023-2-8
Interesting issue. Looks like you have to create a "custom validation function". See if something like this works for you.
a = ones(1, 3);
Test(a)
Test('a')
Test("a")
Test({'a', 'b'})
Test({"a", "b"})
function Test(inputArg1)
arguments
inputArg1 {mustBeStringCharOrCellstr(inputArg1)}
end
disp(inputArg1)
end
function mustBeStringCharOrCellstr(arg)
if ~isstring(arg) && ~ischar(arg) && ~iscellstr(arg)
eid = 'Test:notValid';
msg = 'inputArg1 must be string or char or cellstr';
throwAsCaller(MException(eid, msg))
end
end
3 个评论
Les Beckham
2023-2-8
编辑:Les Beckham
2023-2-8
Good to know. I actually haven't used the argument validation feature very much, so it is nice to learn new things about it so that, if and when I do use it, I will be more prepared.
Creating a cell array of strings, to me, sounds like just poor design, since you can already have arrays of arbitrary length strings. Note that the Matlab editor will even flag the creation of a cell array of strings with a Code Analyzer warning, and offer to fix it by converting it to an array of strings (square brackets instead of curly ones.)
So, maybe you should answer your own question with the mustBeText solution and accept that answer so people looking at this in the future will know about that solution. Note that you can also vote for answers that helped you (such as dpb's and mine) even if they aren't the "right" or accepted answer.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!