如何使用 varargin 和 varargout 包装函数?
Posted
技术标签:
【中文标题】如何使用 varargin 和 varargout 包装函数?【英文标题】:How to wrap a function using varargin and varargout? 【发布时间】:2011-06-21 04:49:03 【问题描述】:小例子:
function varargout = wrapper(varargin)
varargout = someFunction(varargin);
这就是我首先要做的。但是例如,如果someFunction = ndgrid
这会产生一个未定义元胞数组错误,那么下一次尝试使用someFunction(varargin:)
代替。这是一个成功的调用,但是调用[a,b] = wrapper([1,2], [3,4])
不会产生与直接调用ndgrid
相同的结果,那么我做错了什么?
【问题讨论】:
【参考方案1】:其实,米哈伊尔的回答并不完全正确。如果 someFunction 是一个即使没有请求也返回一个值的函数,这是一个函数指示值应该分配给 ans 的方式,Mikhail 的包装器将失败。例如,如果 someFunction 被替换为 sin,并且您将运行 wrapper 与直接运行 sin 进行比较,您会看到:
>> wrapper(0)
>> sin(0)
ans =
0
正确的做法是
function varargout = wrapper( varargin )
[varargout1:nargout] = someFunction( varargin: );
之所以可行,是因为 MATLAB 索引规则中的一个鲜为人知的边缘情况,至少从 R2006a 开始(可能更长)就已经存在这种情况。这在 MATLAB 索引中是一个缺点,但被认为是处理这类事情所必需的。
规则是:
执行下标赋值时,如果
下标分配给未初始化的变量,AND 未初始化的变量被大括号索引,并且 大括号中的索引为空,并且 左侧出现在方括号内,并且 右侧解析为一个值/返回一个输出然后为未初始化的变量分配一个标量单元格,其中包含右侧返回的值。
例如:
>> clear uninit % just to make sure uninit is uninitialized
>> [uninit[]] = sin(0)
uninit =
[0]
【讨论】:
+1 并感谢这份深刻的见解!你从哪里得到上面的规则? 好吧,老实说,如果您可以访问源代码,这会有所帮助...我在 The MathWorks 工作。我不确定这是否正式记录在任何地方。这是帮助高级用户但很容易完全混淆初学者的那些东西之一。但是,我相信这种行为不会改变,因为它需要处理这种情况。 感谢分享,困扰我很久了! 知识渊博,谢谢!我想我可能一直在使用它,甚至没有意识到它为什么起作用:-)【参考方案2】:如果输出参数的数量与输入参数的数量相同,则可以使用
function varargout = wrapper(varargin)
[varargout1:nargin] = someFunction(varargin:);
这适用于ndgrid
。
【讨论】:
除了拼写错误(你肯定是指 varargout1:nargout),请注意这种方法总是返回输出 - 因此是 Mikhail 的额外“~nargout”守卫。 @Edric:我认为使用nargin
是故意的,因为假设nargout=nargin
。在这种情况下,~nargout
警卫是不必要的
@Edric ...另请参阅SCFrench's answer为什么守卫实际上没有产生所需的行为【参考方案3】:
function varargout = wrapper( varargin )
if ~nargout
someFunction( varargin: );
else
[varargout1:nargout] = someFunction( varargin: );
end
【讨论】:
哦,你比我早了 30 秒 :) 我的答案完全相同。以上是关于如何使用 varargin 和 varargout 包装函数?的主要内容,如果未能解决你的问题,请参考以下文章