概括
当使用依赖于参数块中的多个参数的函数参数验证(Repeating)
时,当前参数通常传递给验证函数,而其他参数作为部分填充的元胞数组传递。这与非(Repeating)
参数块中的工作方式不同。这是预期的行为还是错误?
设想
考虑下面的函数dummy1
,它使用自定义参数验证函数
mustBeEqualSize
来确保参数x
和y
具有相同的大小。由于 的验证y
取决于 的值x
,因此我将其称为“交叉参数”验证*。
*如果有更好的术语,请评论或编辑。
function dummy1(x, y)
arguments
x (1,:)
y (1,:) {mustBeEqualSize(x,y)}
end
% Do something with x and y.
end
function mustBeEqualSize(a, b)
% Validates that function arguments have the same size.
if ~isequal(size(a), size(b))
eid = 'Size:notEqual';
msg = "Arguments must have the same size.";
throwAsCaller(MException(eid, msg))
end
end
正如所写,这种形式的参数验证按预期工作:
dummy1(1:3, 4:6) % arguments have same size; validation passes (okay)
dummy1(1:3, 4:7) % arguments have different size; validation fails (okay)
在这两种情况下,mustBeEqualSize
在参数验证期间调用when 时,y
两者都作为 1xN 双数组接收,这符合我的期望:a
b
% Inside call to mustBeEqualSize(x,y), when x=1:3, y=4:6 in dummy1
a =
1 2 3
b =
4 5 6
当被修改为通过添加到参数块dummy1
来接受重复参数时,就会出现问题:(Repeating)
function dummy2(x, y)
arguments (Repeating)
x (1,:)
y (1,:) {mustBeEqualSize(x,y)}
end
% Do something with each pair of x-y arguments.
% In this body, both x and y will be 1xN cell arrays, where N is the
% number of argument groups passed.
end
现在,当我们调用 时dummy2(1:3, 4:6)
,参数验证失败。使用调试器,我发现 whenmustBeEqualSize
在验证期间被调用y
,a
作为 1x1 单元格数组接收,而b
仍然是 1x3 双精度数组:
% Inside call to mustBeEqualSize(x,y), when x=1:3, y=4:6 in dummy2
a =
1×1 cell array
{[1 2 3]}
b =
4 5 6
当使用更多重复参数时,这个问题更加明显:
dummy2(1:3, 4:6, 1:3, 4:6, 1:3, 4:6) % 3 argument groups
结果是
a =
1×3 cell array
{[1 2 3]} {0×0 double} {0×0 double}
b =
4 5 6
似乎在 in 的验证过程y
中dummy2
,y
接受了当前正在验证的参数的值,而x
MATLAB 分配了一个(部分填充的)单元数组缓冲区来保存所有x
传递的 - 参数。
这当然会破坏交叉参数验证,因为只有当前正在验证的参数实际上将自身呈现为单个参数,而其他参数将它们呈现为单元数组缓冲区。
问题
交叉参数验证(Repeating)
与非参数的工作方式之间的不匹配是一个错误,还是MATLAB 不支持(Repeating)
带有参数的交叉参数验证?(Repeating)
如果这种行为差异是意料之中的,有没有办法让交叉参数验证与(Repeating)
参数一起工作?
MATLAB 文档对使用重复参数的参数验证进行了以下说明
在函数中,每个重复参数变成一个元胞数组,其元素数等于函数调用中传递的重复次数。验证应用于元胞数组的每个元素。
这似乎没有说明交叉参数验证应该如何与重复参数一起工作。
使用 MATLAB R2021a (9.10.0.1602886) 进行测试。