代码之家  ›  专栏  ›  技术社区  ›  Jordi

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

  •  112
  • Jordi  · 技术社区  · 15 年前

    是否可以从一个函数中获取“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] = func;
    

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

    8 回复  |  直到 8 年前
        1
  •  37
  •   Community pid    7 年前

    这有点像一个黑客,但它是有效的:

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

    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) 如果你所关心的一切 polyfit 是第三个参数)


    编辑:有更好的方法;请参见 ManWithSleeve's answer 相反。

        2
  •  222
  •   pauldoo    12 年前

    使用matlab 7.9版(r2009 b),您可以使用a~,例如,

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

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

    release notes 详情。

        3
  •  37
  •   user85109    12 年前

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

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

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

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

        4
  •  13
  •   glglgl John Dvorak    12 年前

    这是你可以使用的另一个选项。首先创建一个单元数组以捕获所有输出(您可以使用 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
    
        5
  •  9
  •   shabbychef    15 年前

    我写了一个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;
    % 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);
    

    请注意,使用类似这样的匿名函数会产生开销,我在代码中不会做这样的事情,这将被调用上千次。

        6
  •  4
  •   Sam    14 年前

    在Matlab2010a中,我找到了一个很好的方法来做你想要的。只需使用characher“~”(当然不带引号)作为虚拟变量(返回多个参数时尽可能多)。如果函数被设计用来处理丢失的数据,那么这也适用于函数的输入参数。我不知道以前的版本中是否存在这种情况,但我最近才发现。

        7
  •  1
  •   Dave    12 年前

    您可以生成只返回选定输出的函数(或匿名函数),例如

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

    然后您可以这样调用函数:

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

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

    output(1,2:4) = select(func,1:3);
    
        8
  •  0
  •   Soner Gönül to StackOverflow    11 年前

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

    a=rand([5 10 20 40]);
    
    size(a);
    
    b=ans(2);
    

    给出b=10,这样是否与所有matlab版本都不兼容?

    此外,当您不知道将有多少个参数时,这将用于获取第二个输出参数!鉴于,如果您这样做:

    [~, b] = size(a);
    

    那么b=8000!(您需要以~结尾,以获取更多参数!)