賞金將在 6 天后到期。此問題的答案有資格獲得 100聲望賞金。 Brian想要獎勵一個現有的答案。
概括
當使用依賴于引數塊中多個引數的函式引數驗證(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 雙陣列接收,這符合我的期望:ab
% 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
Now when we call dummy2(1:3, 4:6), argument validation fails. Using the
debugger, I found that when mustBeEqualSize is called during the
validation of y, a is received as a 1x1 cell array while b remains a 1x3 double array:
% 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
The issue is even more obvious when more repeating argument are used:
dummy2(1:3, 4:6, 1:3, 4:6, 1:3, 4:6) % 3 argument groups
results in
a =
1×3 cell array
{[1 2 3]} {0×0 double} {0×0 double}
b =
4 5 6
It seems that during the validation of y in dummy2, y takes on the value of the
current argument being validated while x is a (parially populated)
cell array buffer that MATLAB allocated to hold all of the x-arguments
that were passed.
This of course breaks the cross-argument validation, since only the argument currently being validated actually presents itself as a single argument, while other arguments present themsevles as cell array buffers.
Question
Is the mismatch between how cross-argument validation works for (Repeating) versus non-(Repeating) arguments a bug, or is cross-argument validation with (Repeating) arguments not supported in MATLAB? If this difference in behavior is expected, is there any way to make cross-argument validation work with (Repeating) arguments?
The MATLAB docs say the following about argument validation with Repeating arguments
In the function, each repeating argument becomes a cell array with the number of elements equal to the number of repeats passed in the function call. The validation is applied to each element of the cell array.
which doesn't seem to shed any light on how cross-argument validation should work with repeating arguments.
Tested using MATLAB R2021a (9.10.0.1602886).
uj5u.com熱心網友回復:
注意:這是我們沒有考慮的設計的邊緣案例。我已經讓相關的開發團隊意識到,他們會考慮在未來的版本中修復它。
在短期內,您可以嘗試抓取0x0 double單元格陣列的最后一個非元素:
function mustBeEqualSize(x,y)
if iscell(x)
% Get last non-empty element of `x`
notEmptyDouble = @(e)isa(e,'double') && ~isequal(size(e), [0, 0]);
idx = find(cellfun(notEmptyDouble, x), 1, 'last');
x = x{idx};
end
% check equality
if ~isequal(size(x), size(y))
error("size mismatch")
end
end
這將適用于所有非空陣列,但不幸的是,鑒于使用的空型別,不適用于dummy2([],[]).
另外,我想指出,無論驗證器最終為這個用例作業,考慮如果/當這個問題得到解決時它是否會破壞功能。即,如果此函式需要同時處理雙精度陣列和元胞陣列,將來可能會出現問題。但是,如果此函式只需要雙陣列,則可以使用
arguments(Repeating)
a (1,:) double
b (1,:) double {mustBeEqualSize(x,y)}
end
這與iscell驗證器中的檢查相結合,應該可以證明此功能的未來。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/422692.html
標籤:
上一篇:并排影像-MATLAB報告生成器
下一篇:如何繪制多項式
