我写了一个测试函数,并遇到了inputParser
function doit(varargin)
p = inputParser;
p.KeepUnmatched = 1;
% why does this bomb if I put in @ischar ?
p.addOptional('shape','forgot',@(x) true);
p.addParameter('color', 'k', @(x) true); % 'cause color could be char or triplet
p.parse(varargin{:});
% more code using the parsed inputs
end
如果我跑
doit('hello','color','g')
或
doit('color','g')
使用上面的代码,所有工作都按预期工作。但是,如果我将optional
参数的输入验证更改为
p.addOptional('shape', 'forgot',@(x) ischar)
,我在p.parse(varargin{:})
No value was given for 'g'. Name-value pair arguments require a name followed by a value.
看起来我不理解最终的参数,即应该验证输入参数的匿名函数。有什么问题?
Win7上的Matlab 2015a。
似乎varargin
中每个参数的确切类别会影响行为。
function threeout = argthree( varargin)
p = inputParser;
p.KeepUnmatched = true;
%defshape = 'forgot';
defshape = 5;
addOptional(p,'shape',defshape,@isnumeric);
addParameter(p,'color', 'k',@ischar); %
parse(p, varargin{:});
threeout = p.Results;
end
至少有两件事可能导致parse()失败。第一:这:
>> argthree('nono','color','vu')
Error using argthree (line 10)
No value was given for 'vu'. Name-value pair arguments require a name followed by a value.
请注意,即使可选的“形状”应该针对数字进行测试,但解析器似乎认为“nono”是名称 - 值对的开头。
Entering either a numer or nothng works:
>> argthree('color','vu')
ans =
color: 'vu'
shape: 5
>> argthree(7,'color','vu')
ans =
color: 'vu'
shape: 7
现在替换addOptional行而不进行验证:
addOptional(p,'shape',defshape );
为所有三个电话获得与上述相同的结果。
现在将默认值更改为
defshape = 'forgot' % a charstring
>> argthree('nono','color','vu')
Error using argthree (line 10)
No value was given for 'vu'. Name-value pair arguments require a name followed by a value.
>> argthree('color','vu')
ans =
color: 'vu'
shape: 'forgot'
>> argthree(7,'color','vu')
ans =
color: 'vu'
shape: 7
现在尝试验证字符串输入:再次替换addOptional行 -
addOptional(p,'shape',defshape,@ischar );
>> argthree('nono','color','vu')
ans =
color: 'vu'
shape: 'nono'
>> argthree('color','vu')
Error using argthree (line 10)
No value was given for 'vu'. Name-value pair arguments require a name followed by a value.
>> argthree(7,'color','vu')
Error using argthree (line 10)
The value of 'shape' is invalid. It must satisfy the function: ischar.
这里有一些非常不一致的parse()
尝试将varargin{:}
与参数列表(可选或名称 - 值对)匹配的方式。由于发生了不一致的失败,我无法设置一个带有Optional char参数后跟一个名称 - 值对的情况,就我所见。
我在MathWorks上提交了一份错误报告,“技术支持案例#02121531”,他们能够重现这个问题。
答案 0 :(得分:1)
tl; dr 尝试
@ischar
或@(x) ischar(x)
代替@(x) ischar
<强>解释强>
我怀疑错误消息不合适,并且只是由验证函数引发错误导致的一般错误。 Matlab允许两种验证功能:
我怀疑在后一种情况下,matlab只会喷出一条关于你无法传递适当参数的通用无法提供的错误消息。
我认为您的问题可能是,在您的匿名函数中,您实际上是在没有参数的情况下调用ischar
(函数 name ),这会导致错误。这会引发异常,并且matlab会将此解释为您的验证函数抛出异常以表示解析失败。
因此将@(x) ischar
替换为@ischar
或@(x) ischar(x)
(它们都是对应于单参数函数的有效函数句柄),它应该有效(假设没有其他错误)。< / p>
答案 1 :(得分:1)
我一直在与MathWorks,技术支持案例#02121531讨论这个问题。
我写了一篇关于我希望做什么的解释:
我希望能够有一个可选参数 字符串,然后是一个或多个值 - 参数对 其中的参数是字符串。因为我将“可选”解释为 只是那个,即没有的varargin {:}元素之一 需要存在,我期望以下两个命令 会工作:
foop =parseCheck('nono','color','vu');
和
foop =parseCheck('color','vu');
然而, 解析器函数似乎无法理解“'color'”是一个 值 - 参数对中的值。解析器看到一个字符串 作为第一个varargin并立即将其标识为Optional 参数。我的观点是,这既不直观也不可取。
我认为这是一个错误,并建议解析器代码 重写,以便任何与任何“Value”字符串匹配的字符串 首先测试它是否导致有效的值参数对,和 只有在那之后才应该测试初始的varargin {:}元素 反对可选参数验证。
基本上,我说你不能称之为“可选”的论据 必须存在才能使解析器正常运行。
我发现的最后一个是引用他们的支持者,
感谢您在调查此问题时的耐心等待。在 您发送的示例中,'color'确实作为可选项使用 参数'形状'。这种情况正在发生,因为目前,位置 参数优先于名称/值对。我为此道歉 给您带来的不便。我已经分享了你的工作流程 与开发人员的关注和您的建议以及增强功能 请求已提交。它将在未来的版本中考虑 MATLAB。
答案 2 :(得分:0)
这实际上并不是一个错误。验证功能不够具体,这是一个问题。仅使用ischar
作为验证函数意味着参数名称可能被误解为有效值。很可能,我希望您的输入具有一组固定的有效值,而您应该检查输入是否是该集合的有效成员。这是一个例子:
p = inputParser;
addOptional(p, 'shape', 'forgot', @(s) ismember(s, {'square', 'circle', 'triangle'}));
addParameter(p, 'color', 'k', @(c) ismember(c, 'ymcrgbwk'));
您可以根据需要使验证功能更复杂,可能会anonymous functions改为function handles而不是local functions。例如,您可以检查数据类型然后检查值,或者您可以检查'color'
参数是a single character or an RGB triplet。
可能导致混淆的部分原因是将'KeepUnmatched'
设置为true,这将存储不匹配的参数值对,并且不会抛出与inputParser
object的预期参数不匹配的任何错误。第二次编辑的第一个示例(使用numeric
作为验证函数)在输入参数列表中找不到数值,因此将'shape'
设置为默认值。由于解析器接下来会查找参数值对,因此字符串'nono'
和'color'
将成为不匹配的对,并存储在解析器对象的'Unmatched'
属性中。仍在寻找有效的参数 - 值对,解析器只找到'vu'
,假设它是一个不匹配的参数字符串。
我遵循的一般经验法则:尽可能使您的验证功能具体化。