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

时间:2009-04-14 12:28:49

标签: matlab function return-value

是否可以从函数中获取'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;

我仍然认为这是非常难看的代码,但如果没有更好的方法,那么我想我会接受答案。

8 个答案:

答案 0 :(得分:223)

使用MATLAB版本7.9(R2009b),您可以使用〜,例如

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

请注意,,不是可选的。只需输入[~ ~ var]将无法正常工作,并会抛出错误。

有关详细信息,请参阅release notes

答案 1 :(得分:38)

这有点像黑客,但它有效:

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

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

(编辑:只是为了检查,我还验证了如果[mu,mu,mu]=polyfit(x,y,n)所关心的所有内容都是第3个参数,这项技术适用于polyfit


编辑:有一个更好的方法;请改为ManWithSleeve's answer

答案 2 :(得分:37)

如果你想使用一个变量将留在比特桶中的样式,那么一个合理的替代方案是

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

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

虽然我确实喜欢MATLAB现在允许的新技巧,但是使用〜来指定一个被忽略的返回变量,这是向后兼容性的问题,因为旧版本的用户将无法使用您的代码。在发布至少一些MATLAB版本之前,我通常会避免使用类似的新东西,以确保很少有用户留在困境中。例如,即使是现在我发现人们仍然使用足够旧的MATLAB版本,他们不能使用匿名函数。

答案 3 :(得分:13)

这是您可以使用的另一个选项。首先使单元格数组捕获所有输出(您可以使用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

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

答案 4 :(得分:9)

我写了一个第k个函数:


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;
% global:
% nb: 
% See also:
% todo:
% changelog: 
%
%% %UNFOLD

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

end %function
然后你可以打电话

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

你也可以把这个功能包起来像

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

之后使用

val_i_want = func_i_want(func_input_1,func_input_2);

请注意,使用像这样的匿名函数会产生开销,而且我不会在代码中进行数千次调用。

答案 5 :(得分:4)

在Matlab 2010a中,我发现了一种巧妙的方式来做你想要的。简单地使用characher“〜”(当然没有引号)作为虚拟变量(返回多个参数时可以使用多个)。如果函数设计用于处理缺失数据,这也适用于函数的输入参数。我不知道以前的版本是否存在这种情况,但我最近才发现它。

答案 6 :(得分:1)

您可以创建仅返回所选输出的函数(或匿名函数),例如

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

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

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

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

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

答案 7 :(得分:0)

有没有理由不使用ans(n),像这样:

a=rand([5 10 20 40]);

size(a);

b=ans(2);

给b = 10,这样与所有Matlab版本不兼容吗?

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

[~, b] = size(a);

然后b = 8000! (你需要以〜结束,以获得更多的论点!)