如何使用 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 包装函数?的主要内容,如果未能解决你的问题,请参考以下文章

Matlab learning summary

matlab常用函数名``谁给我个啊``谢谢`

matlab 中关于 varargin 参数

M文件变量检测与传递

matlab中语句mean(varargini(:))啥意思?

matlab中cell数组问题