如何传播(或内省)nargout?

时间:2014-02-27 23:52:04

标签: matlab

是否有内置方法可以自动将调用函数的nargout传播到被调用函数? (或者一些被调用的函数可以找出调用函数的nargout?)

例如,说

% foo.m
function [X, Y] = foo()
    [X, Y] = bar();
end

% bar.m
function [X, Y] = bar()
    X = 1;
    if upstream_nargout() < 2
        Y = 0;
    else
        Y = big_nasty_time_consuming_monster();
    end
end

当然,人们总是可以像这样定义foo

% foo.m
function [X, Y] = foo()
    if nargout < 2
        X = bar();
    else
        [X, Y] = bar();
    end
end

...或者用额外的参数来定义bar来携带调用者的nargout,但是我想知道是否有合理的方法来实现相同的效果而不诉诸于此。

2 个答案:

答案 0 :(得分:2)

varargoutnargout的工作原理如下:

% foo.m
function varargout = foo()
    [varargout{1:nargout}] = bar();
end

% bar.m
function varargout = bar()
    varargout{1} = 1;
    if nargout > 1,
        fprintf('bar: computing second output\n');
        varargout{2} = rand(); % OR big_nasty_time_consuming_monster();
    end
end

然后:

>> X = foo
X =
     1
>> [X,Y] = foo
bar: computing second output
X =
     1
Y =
    0.5647

注意:&{34;后面的问题中foo的版本;当然,人们可以像这样定义foo&#34;肯定会有效,但是这个替代方案允许您在foo调用bar而不是另一个if / else中使用一行。当我读到这个问题时,这就是问题的关键。

答案 1 :(得分:1)

我认为没有任何理由宣传调用者,这应符合您的要求:

function [X, Y] = foo()
    if nargout < 2
        X = bar();
    else
        [X, Y] = bar();
    end
end

function [X, Y] = bar()
    X = 1;
    if nargout < 2
        Y = 0;
    else
        Y = big_nasty_time_consuming_monster();
    end
end

如果你真的需要calles nargout使用evalin('caller','nargout'),但我永远不会将nargin / nargout与evalin('caller'结合起来,你就可以轻松生成无法调试的代码。