如何优雅地忽略 MATLAB 函数的一些返回值

有没有可能从一个函数中获得‘ nth’返回值,而不必为之前的所有 n-1返回值创建虚拟变量?

比方说,我在 MATLAB 中有以下函数:

function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;

现在假设我只对 第三返回值感兴趣,这可以通过创建一个虚拟变量来实现:

[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;

但我觉得这有点像 丑陋。我认为你可以做下面的事情之一,但是你不能:

[_, _, variableThatIWillUse, _] = func;

[, , variableThatIWillUse, ] = func;

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

有没有什么 优雅的方法可以做到这一点呢?


到目前为止,最好的解决方案是简单地使用 variableThatIWillUse作为虚拟变量。这样我就不必创建一个真正的虚拟变量来污染工作空间(或者我需要清除的空间)。简而言之: 解决方案是对每个返回值使用 variableThatIWillUse,直到出现感兴趣的返回值为止。返回值之后可以简单地忽略:

[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;

I still think this is very ugly code.

56863 次浏览

这有点像黑客行为,但它确实有效:

首先是一个快速示例函数:

Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3

现在这里的关键是,如果在多表达式赋值的左边使用变量 两次,那么前面的赋值会被后面的赋值消灭:

[b,b,c]=Func3();
% yields b=2, c=3


[c,c,c]=Func3();
% yields c=3

(Just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the third argument.)


还有一种更好的方法; 请参见 ManWithSleeve's answer

这里还有一个你可以用的选择。首先创建一个单元格数组来捕获所有输出(可以使用 NARGOUT函数来确定给定函数返回的输出数量) :

a = cell(1,3);  % For capturing 3 outputs
% OR...
a = cell(1,nargout(@func));  % For capturing all outputs from "func"

然后调用函数如下:

[a{:}] = func();

然后简单地从 中删除所需的元素,并覆盖 :

a = a{3};  % Get the third output

如果您希望使用一种样式,其中变量将留在位桶中,那么一个合理的替代方案是

[ans, ans, variableThatIWillUse] = myfun(inputs);

ans当然是 MATLAB 默认的垃圾变量,在会话过程中经常被覆盖。

虽然我很喜欢 MATLAB 现在允许的新技巧,使用 ~来指定一个被忽略的返回变量,但这是一个向后兼容性问题,因为使用旧版本的用户将无法使用您的代码。

我一般避免使用这样的新东西,直到至少有几个 MATLAB 版本已经发布,以确保将有很少的用户留在困境。例如,即使现在我发现人们仍然使用一个足够老的 MATLAB 版本,他们不能使用匿名函数。

我写了一个 kth out 函数:

function kth = kthout(k, ffnc, varargin)
% kthout: take the kth varargout from a func call %FOLDUP
%
% kth = kthout(k, ffnc, varargin)
%
% input:
%  k                      which varargout to get
%  ffnc                   function to call;
%  varargin               passed to ffnc;
% output:
%  kth                    the kth argout;


[outargs{1:k}] = feval(ffnc, varargin{:});
kth = outargs{k};


end %function

然后你可以打电话

val_i_want = kthout(3, @myfunc, func_input_1, func_input_2);

你也可以像这样结束这个函数:

func_i_want = @(varargin)(kthout(3, @myfunc,varargin{:}));  % Assuming you want the third output.

之后你再用

val_i_want = func_i_want(func_input_1, func_input_2);

请注意,使用这样的匿名函数会产生一些开销,我不会在代码中这样做,因为这样的代码会被调用数千次。

With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,

[~, ~, variableThatIWillUse] = myFunction();

请注意,,不是可选的。只键入 [~ ~ var]将不起作用,并将抛出一个错误。

有关详细信息,请参阅 释放通知书

在 MATLAB 2010a 中,我找到了一种简单的方法来满足你的要求。

它只是简单地使用字符“ ~”(当然不带引号)作为虚拟变量(在返回多个参数时想要多少就多少)。如果函数的设计目的是处理丢失的数据,那么这也适用于函数的输入参数。

我不知道这在以前的版本中是否存在,但我最近才发现它。

可以创建一个只返回选定输出的函数(或匿名函数) ,例如。

select = @(a,b) a(b);

然后你可以这样调用你的函数:

select(func,2);
select(func,1:3);

或者可以将输出分配给一个变量:

output(1,2:4) = select(func,1:3);

我看不出有什么理由不使用 ans (n) ,比如:

size(rand([5 10 20 40]));


b = ans(2);

It gives b = 10, and this way would be compatible with all MATLAB versions. Note that size() here is just used to represent any function that has multiple return variables.

此外,当您不知道将有多少个参数时,这种方法可以获得第二个输出参数!然而,如果你这样做:

[~, b] = size(a);

然后 b = 8000! (您需要以 ~结束,以捕捉更多参数!)