如何优雅地忽略MATLAB函数的一些返回值?
是否有可能从函数中获得“第n个”返回值,而不必为之前的所有n-1
返回值创build虚拟variables?
比方说,我在MATLAB中有以下function:
function [a,b,c,d] = func() a = 1; b = 2; c = 3; d = 4;
现在假设,我只对第三个返回值感兴趣。 这可以通过创build一个虚拟variables来完成:
[dummy, dummy, variableThatIWillUse, dummy] = func; clear dummy;
但是我觉得这样很丑 。 我认为你可能会做下面的事情之一,但是你不能:
[_, _, variableThatIWillUse, _] = func;
[, , variableThatIWillUse, ] = func;
variableThatIWillUse = func(3);
variableThatIWillUse = func()(3);
有没有什么优雅的方法来做到这一点工作?
到目前为止,最好的解决scheme是简单地使用variableThatIWillUse
将使用作为一个虚拟variables。 这使我不必创build一个真正的虚拟variables,污染工作空间(或者我需要清除)。 简而言之:解决scheme是使用variableThatIWillUse
将使用每个返回值,直到有趣的。 返回值可以简单地忽略:
[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
我仍然认为这是非常丑陋的代码,但如果没有更好的方法,那么我想我会接受答案。
这有些黑客,但它的作品:
首先是一个快速示例函数:
Func3 = @() deal(1,2,3); [a,b,c]=Func3(); % yields a=1, b=2, c=3
现在关键在于,如果在多expression式赋值的左侧使用两次variables,则较早的赋值将被后面的赋值所破坏:
[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的答案 。
使用MATLAB版本7.9(R2009b),您可以使用〜,例如,
[~, ~, variableThatIWillUse] = myFunction();
请注意,这不是可选的。 只要input[~ ~ var]
将无法正常工作,并会引发错误。
详细信息请参阅发行说明 。
如果你想使用一个variables将落入位桶的风格,那么一个合理的select是
[ans,ans,variableThatIWillUse] = myfun(inputs);
ans当然是matlab的默认垃圾variables,在会话过程中经常被覆盖。
虽然我喜欢MATLAB现在允许的新技巧,但是使用〜来指定忽略的返回variables,这是向后兼容性的一个问题,因为旧版本的用户将无法使用您的代码。 我通常避免使用类似的新东西,直到至less发布了几个MATLAB版本,以确保将有很less的用户留在这个困境中。 例如,即使现在我发现人们仍在使用足够老的MATLAB版本,他们不能使用匿名函数。
这是另一个可以使用的选项。 首先制作一个单元格arrays来捕获所有的输出(你可以使用NARGOUT函数来确定一个给定的函数返回多less输出):
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
我写了第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
你也可以像这样包装function
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);
请注意,与使用这种匿名函数相关的开销,这是不是我会在数千次的代码中做的事情。
在Matlab 2010a中,我find了一个干净利落的方法来做你所要求的。 只需使用字符“〜”(当然没有引号)作为你的虚拟variables(当你返回多个参数的时候你想要的数量就多)。 如果函数devise为处理丢失的数据,这也适用于函数的input参数。 我不知道以前的版本是否存在,但是我刚刚碰到它。
你可以做一个函数(或匿名函数),只返回选定的输出,例如
select = @(a,b) a(b);
然后你可以这样调用你的函数:
select(func,2); select(func,1:3);
或者你可以把输出分配给一个variables:
output(1,2:4) = select(func,1:3);
是否有任何理由不使用ans(n),如下所示:
a=rand([5 10 20 40]); size(a); b=ans(2);
给b = 10,这样就不能兼容所有的Matlab版本?
而且,当你不知道会有多less个参数的时候,这会得到第二个输出参数! 而如果你这样做:
[~, b] = size(a);
那么b = 8000! (你需要以〜结尾,以获得更多的论据!)
我发现如果你只需要一个输出,你可以交叉乘以相应的输出所需的单位matrix的function。 即out_arg_the_third = function(input_args)* [0; 0; 1; 0];
或者变得越来越复杂,你可以扩展你的matrix的尺寸来收集更多的输出:out_arg_second_and_third = function(input_args)* [0,0; 1,0; 0,1; 0,0]; 但是我们在这里开始失去一些优雅。
新版本必须有更好的方法,但由于我不明白我需要使用2007b