Tl; Dr:在Matlab的新(2019b)函数参数验证中,有没有办法提供无与伦比的可选名称/值参数?
我现有的Matlab代码使用输入解析器向sim派发可选参数。设置sim卡时,你可以选择一些函数来指示对象在其环境中的行为,然后调用runSim
。在这个虚构的示例中,我的sim被定义为具有两个函数的函数,这些函数同时具有唯一的和公共的可选输入。
runSim('sharedArg', sa, 'func1Arg1', f1a1, 'func1Arg1', f1a2, 'func2Arg1', f2a1)
runSim
将调用你选择的定义sim的适当函数,并将这些可选参数传递给每个函数。在这种情况下,输入解析器func1
将忽略func2arg1
,输入解析器func2
将忽略func1Arg1
和func1Arg2
。
一切都很好,但是我的Sim花费了三分之一的时间进行输入解析,因为这些函数在循环中被调用了数千次。Matlab的输入解析器有一个记录为缓慢的历史记录(在此处插入亵渎)。
在最近更新到2020a之后,我发现了函数参数验证,它比输入解析器的可怕得多。在许多功能中进行了测试,不仅使代码更具可读性,而且我看到了性能的巨大提升。
function output = func1FirstTry(options)
% This function does some things
arguments
options.sharedArg
options.func1Arg1 double = 1
options.func1Arg2 double = 2
end
output = 2;
end
爱它。伟大的。惊人的。但...
...新的函数验证不允许使用不匹配的参数(或者至少链接的页面没有对此进行解释,并且我还没有找到任何更详尽的文档)。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。以前,func1
只需要了解其可选参数即可。如果将我指定func2arg1
为的输入func1
,它将被忽略。使用新的函数验证时,这将引发错误,因为我尚未func2Arg1
在arguments块中将其定义为允许的输入。因此,当我进行此测试时,我不得不执行以下操作:
function output = func1SecondTry(options)
% This function does some things
arguments
options.sharedArg
options.func1Arg1 double = 1
options.func1Arg2 double = 2
options.func2Arg1 double = Nan
end
% Rest of the code goes here
end
现在可以使用,但是我还必须更改func2
为接受func1
的可选参数。而且,我还有20多个函数需要考虑使用可选参数,因此显然,这种策略不会奏效。有没有一种方法可以指定我想以与输入解析器相同的方式接受和忽略任何未命名的可选输入?具体来说,我希望func1FirstTry('func2Arg1', 3)
不会出错,而无需添加func2Arg1
到arguments块。
最终这不是我采用的解决方案,但是我认为可能的答案是定义一个虚拟类,将对解析器的所有可能输入作为公共属性,然后使用类属性语法中的值。因此,该类的所有属性都是对函数的合法输入,但是你将仅访问特定于该函数的参数。如果要更改默认值,此语法还允许你重新定义任何特定参数。
% Define this in its own file
classdef OptionalArgumentClass
properties
sharedArg
func1Arg1
func1Arg2
func2Arg1
argumentUndefinedByOtherFunctions
end
end
% In a separate file from class
function output = func1(options)
% This function does some things
arguments
options.?Path.To.OptionalArgumentClass
options.func1Arg1 = 1 % Can choose specific default values here if needed
end
% options.func1Arg2 has no default value, so this will error if unspecified
output = options.func1Arg1 + options.func1Arg2;
end
包含的options.?Path.To.OptionalArgumentClass
意思是我可以指定func2Arg1
或argumentUndefinedByOtherFunctions
希望它们被优美地忽略,这就是我一直在寻找的东西。