如何使用varargin和varargout包装函数?

Tob*_*ler 31 matlab variadic-functions wrapper

小例子:

function varargout = wrapper(varargin)
varargout = someFunction(varargin);
Run Code Online (Sandbox Code Playgroud)

这就是我先做的事情.但是,例如,如果someFunction = ndgrid这产生了未定义的单元格数组错误,那么下一次尝试就是使用了someFunction(varargin{:}).这是一个成功的通话,但是通话[a,b] = wrapper([1,2], [3,4])不会产生与直接通话相同的结果ndgrid,所以我做错了什么?

SCF*_*nch 36

实际上,米哈伊尔的答案并不完全正确.如果someFunction是一个函数,即使没有请求也返回一个值,这就是函数指示该值应该分配给ans的方式,Mikhail的包装器将失败.例如,如果someFunction被sin替换,并且你直接比较了运行包装器和运行sin,你会看到:

>> wrapper(0)
>> sin(0)

ans =

   0
Run Code Online (Sandbox Code Playgroud)

正确的方法是

function varargout = wrapper( varargin )
[varargout{1:nargout}] = someFunction( varargin{:} ); 
Run Code Online (Sandbox Code Playgroud)

这种方法起作用的原因是由于MATLAB索引规则中的一个鲜为人知的边缘情况,因为至少R2006a(可能更长),这种情况恰好存在于这种情况下.它在MATLAB索引中是一种瑕疵,但被认为是处理这类事情所必需的.

规则是:

执行下标分配时,如果

  • 下标 - 分配给未初始化的变量AND
  • 未初始化的变量是卷括号索引,AND
  • 花括号中的索引为空,AND
  • 左侧出现在方括号内,AND
  • 右侧解析为值/返回输出

然后为未初始化的变量分配一个标量单元格,其中包含右侧返回的值.

例如:

>> clear uninit % just to make sure uninit is uninitialized
>> [uninit{[]}] = sin(0)

uninit = 

    [0]
Run Code Online (Sandbox Code Playgroud)

  • 嗯,说实话,如果你有权访问源代码,那将会很有帮助......我为The MathWorks工作.我不确定这是否正式记录在案.这是帮助高级用户但却很容易让初学者感到困惑的事情之一.但是,我相信这种行为不会改变,因为它需要处理这种情况. (7认同)
  • +1 并感谢这个深刻的见解!你从哪里得到上面的规则? (2认同)

Mik*_*ail 7

function varargout = wrapper( varargin )

if ~nargout
    someFunction( varargin{:} ); 
else
    [varargout{1:nargout}] = someFunction( varargin{:} ); 
end
Run Code Online (Sandbox Code Playgroud)