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

Jor*_*rdi 117 matlab function return-value

是否有可能从函数中获取'nth'返回值而不必为n-1之前的所有返回值创建虚拟变量?

比方说,我在MATLAB中有以下功能:

function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
Run Code Online (Sandbox Code Playgroud)

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

[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
Run Code Online (Sandbox Code Playgroud)

但我认为这有点难看.我认为你可能会做以下事情之一,但你不能:

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

[, , variableThatIWillUse, ] = func;

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

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


到目前为止,最好的解决方案是简单地使用variableThatIWillUse虚拟变量作为虚拟变量.这使我不必创建一个污染工作空间的真实虚拟变量(或者我需要清除它).简而言之:解决方案是使用variableThatIWillUsefor each返回值直到有趣的值.之后的返回值可以简单地忽略:

[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
Run Code Online (Sandbox Code Playgroud)

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

小智 225

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

[~, ~, variableThatIWillUse] = myFunction();
Run Code Online (Sandbox Code Playgroud)

请注意,这,不是可选的.只是打字[~ ~ var]不起作用,并会抛出错误.

有关详细信息,请参阅发行说明

  • 请注意,`,`不是可选的.只输入`[~~ var]`将*不*工作,并将抛出错误. (28认同)
  • 这个问题是在2009年R2009b之前提出的,那时〜没有用. (6认同)
  • @SamB:虽然使用`not`操作符,但"不关心"也不是那么糟糕 (4认同)
  • 有点烦人的不是"_".(我想这已经被拍了?) (3认同)
  • 我会说这是“正确”的答案。其他只是解决不存在的问题的技巧。虽然没有双关语... (2认同)

Jas*_*n S 38

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

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

Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
Run Code Online (Sandbox Code Playgroud)

现在关键在于,如果在多表达式赋值的左侧使用两次变量,则先前的赋值会被后面的赋值所破坏:

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

[c,c,c]=Func3();
% yields c=3
Run Code Online (Sandbox Code Playgroud)

(编辑:只是为了检查,我还验证了[mu,mu,mu]=polyfit(x,y,n)如果您关心的polyfit是第3个参数,这种技术可以使用)


编辑:有一个更好的方法; 相反,请参阅ManWithSleeve的答案.

  • 没想过像这样解决它.但是,我觉得这种解决方案牺牲了聪明意图的清晰度. (7认同)
  • 我个人只是使​​用[junk,junk,c] = function_call()并假设"垃圾"永远不是一个重要的变量,如果它包含大量内存,我会在必要时清除它. (5认同)
  • 对于downvoter:为什么-1?这个答案是在R2009b发布之前写的,所以@ ManWithSleeve的回答当时不会有效.当然,现在,这是正确的方法. (5认同)
  • 也许在答案的第一行中发表评论会有所帮助?我只是通过google来到这里的,所以似乎值得更新。 (2认同)

小智 37

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

[ans,ans,variableThatIWillUse] = myfun(inputs);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 您可以关闭警告.使用此注释字符串结束该行%#ok Mlint将忽略此项.没有警告. (11认同)
  • 是的,它很聪明,但是如果你为ans变量赋值,那么本机Matlab编辑器会发出警告.我不认为警告很优雅...... (7认同)

gno*_*ice 13

这是您可以使用的另一个选项.首先创建一个单元格数组来捕获所有输出(您可以使用NARGOUT函数来确定给定函数返回的输出数量):

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

然后按如下方式调用该函数:

[a{:}] = func();
Run Code Online (Sandbox Code Playgroud)

然后,只需从删除元素一个你想要的,并覆盖:

a = a{3};  % Get the third output
Run Code Online (Sandbox Code Playgroud)


sha*_*hef 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
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话

val_i_want  = kthout(3,@myfunc,func_input_1,func_input_2); %etc
Run Code Online (Sandbox Code Playgroud)

你也可以像这样结束这个功能

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

之后你使用

val_i_want = func_i_want(func_input_1,func_input_2);
Run Code Online (Sandbox Code Playgroud)

请注意,使用这样的匿名函数会产生开销,而这在我将要调用数千次的代码中不会发生.