【问题标题】:How to wrap a function using varargin and varargout?如何使用 varargin 和 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 相同的结果,那么我做错了什么?

【问题讨论】:

    标签: matlab wrapper variadic-functions


    【解决方案1】:

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

    >> wrapper(0)
    >> sin(0)
    
    ans =
    
       0
    

    正确的做法是

    function varargout = wrapper( varargin )
    [varargout{1: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)
    [varargout{1:nargin}] = someFunction(varargin{:});
    

    这适用于ndgrid

    【讨论】:

    • 除了拼写错误(你肯定是指 varargout{1:nargout}),请注意这种方法总是返回输出 - 因此是 Mikhail 的额外“~nargout”守卫。
    • @Edric:我认为使用nargin 是故意的,因为假设nargout=nargin。在这种情况下,~nargout 警卫是不必要的
    • @Edric ...另请参阅SCFrench's answer为什么守卫实际上没有产生所需的行为
    【解决方案3】:
    function varargout = wrapper( varargin )
    
    if ~nargout
        someFunction( varargin{:} ); 
    else
        [varargout{1:nargout}] = someFunction( varargin{:} ); 
    end
    

    【讨论】:

    • 哦,你比我早了 30 秒 :) 我的答案完全相同。
    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 2019-01-08
    • 2013-06-22
    • 1970-01-01
    相关资源
    最近更新 更多