我有一个脚本,由于运行时间过长而可能会中止,之后会继续。我们假设看起来有点像这样:
data = []; % can't preallocate as I don't know the number of entries yet here...
while(1)
% ...
data = [data; someNewEntry];
end
关于它的好处是,当作为脚本运行时,每当我中止它时,我在te工作区中都有变量data
。
但是我想把它转换成一个函数,因为脚本有很多变量,并且用它来填满我的工作区。我们假设我现在将其转换为:
function data = myFnc()
data = []; % can't preallocate as I don't know the number of entries yet here...
while(1)
% ...
data = [data; someNewEntry];
end
问题nnow是:当我中止该功能时,我正在丢失data
中已经为此做出的所有条目。如何解决此问题并在中止函数时返回当前向量data
?我想出的唯一可能的解决方案就是在for-loop中使用类似的东西:
if(nargout == 1)
assignin('caller','data', data);
end
但不知怎的,我不太喜欢这种做法。但好吧,对我来说似乎没问题。但有一点仍然让我烦恼:使用它时我总是将数据分配给workspace-var data
,因为我不知道如何获取调用者的输出变量的名称(即{{1 }} - >它将是bla = myFnc()
,因此bla
)。我知道有matlab函数assignin('caller','bla', data);
但我找不到输出变量的等价物。
非常感谢提前!
答案 0 :(得分:3)
我可以想到2个推荐的解决方案:
<强> 1。中断功能而不会丢失工作区
正如我所描述的here,如果你总是打开
,这应该不是问题`dbstop if error`
<强> 2。经常保存变量
使用您的assignin解决方案,您已经接近,因为它将变量“保存”到基础工作区。但是,这仍然不是存储变量的非常安全的空间。因此我建议用以下方法保存它们:
save data data
如果第二个选项太过性能杀手,那么你可以每1000次迭代就做一次。
答案 1 :(得分:1)
一种解决方案可能是使用全局变量。使用简单计数器的示例:
function data = myFnc()
global data; % make it a global
if isempty(data) % not yet initialized
data = [];
end
i = 1;
while(i < 10)
pause(1)
disp(i)
data = [data, i];
i = i + 1;
end
然后在命令行上,您必须执行global data
一次,然后才能访问已保存的状态。快速测试,我在运行时用CTRL + C中止了程序:
>> clear
>> clear global
>> x = myFnc();
1
2
3
4
Operation terminated by user during myFnc (line 10)
>> x
Undefined function or variable 'x'.
>> data
Undefined function or variable 'data'.
>> global data
>> data
data =
1 2 3 4
通常不建议使用全局变量,但有时它们可能很有用。我有时使用全局变量来缓存昂贵的计算,这样每次启动Matlab时它只需要计算一次:
global data;
if isempty(data)
data = expensive_calculation();
end
对于复杂的程序,可能有更简洁的方法将一些状态从一次迭代保存到另一次迭代(实现一些对象?,将状态对象从一次迭代传递到另一次迭代?,保存到文件?),但对于一些快速和脏脚本,使用全局变量可能是最简单的方法。
答案 2 :(得分:1)
另一个选择是使用MATLAB参考类型变量。例如,您可以使用containers.Map
,如下所示:
m = containers.Map();
myFcn(m);
% Later, after hitting CTRL-C
m('data') % get latest value
使用这样的函数:
function myFcn(map)
data = [];
while true
data = [data, rand()];
map('data') = data;
end