是否可以从函数中获取“第 n 个”返回值,而不必为之前的所有 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;
我仍然认为这是非常丑陋的代码。
使用 MATLAB 版本 7.9 (R2009b),您可以使用 ~,例如,
[~, ~, variableThatIWillUse] = myFunction();
请注意,,
不是可选的。仅键入 [~ ~ var]
将不起作用,并且会引发错误。
有关详细信息,请参阅 release notes。
这有点像黑客,但它有效:
首先是一个简单的示例函数:
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
(只是为了检查,如果您只关心 polyfit
中的第三个参数,我还验证了此技术适用于 [mu,mu,mu]=polyfit(x,y,n)
。)
有更好的方法;请参阅 ManWithSleeve's answer。
如果您希望使用将变量留在位桶中的样式,那么一个合理的选择是
[ans, ans, variableThatIWillUse] = myfun(inputs);
ans
当然是 MATLAB 的默认垃圾变量,在会话过程中经常被覆盖。
虽然我确实喜欢 MATLAB 现在允许的新技巧,即使用 ~
指定忽略的返回变量,但这是向后兼容性的问题,因为旧版本的用户将无法使用您的代码。
在至少发布几个 MATLAB 版本之前,我通常会避免使用类似的新东西,以确保只有很少的用户会陷入困境。例如,即使现在我发现人们仍在使用足够旧的 MATLAB 版本,以至于他们无法使用匿名函数。
这是您可以使用的另一个选项。首先创建一个元胞数组来捕获所有输出(您可以使用 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
我写了一个第 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;
[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);
请注意,使用这样的匿名函数会产生开销,这不是我在会被调用数千次的代码中做的事情。
在 MATLAB 2010a 中,我找到了一种巧妙的方式来满足您的要求。
它只是使用字符“~”(当然不带引号)作为你的虚拟变量(返回多个参数时,你想要多少就多少)。如果函数旨在处理丢失的数据,这也适用于函数的输入参数。
我不知道这是否存在于以前的版本中,但我最近才遇到它。
您可以创建一个仅返回选定输出的函数(或匿名函数),例如
select = @(a,b) a(b);
然后你可以这样调用你的函数:
select(func,2);
select(func,1:3);
或者您可以将输出分配给变量:
output(1,2:4) = select(func,1:3);
decimatedfftx = select(fft(x,12),1:4:12);
select(func,2)
调用 func(2)
。我看不出它在哪里选择输出参数。
我看不出有任何理由不使用 ans(n)。像这样:
size(rand([5 10 20 40]));
b = ans(2);
它给出 b = 10,这种方式将与所有 MATLAB 版本兼容。请注意,此处的 size() 仅用于表示具有多个返回变量的任何函数。
此外,当您不知道会有多少参数时,这可以获取第二个输出参数!然而,如果你这样做:
[~, b] = size(a);
那么b = 8000! (您需要以 ~
结尾,以获取更多参数!)
size(a)
和 [b,c]=size(a)
返回不同的东西。 MATLAB 中的函数会根据输出参数的数量改变行为。
不定期副业成功案例分享
don't care
中使用not
运算符也不是那么糟糕,
不是可选的。仅键入[~ ~ var]
将不起作用,并且会引发错误。