Matlab:真正的全局变量

5

可能重复:
在MATLAB中声明全局变量

目前我的MATLAB代码是一个大的脚本文件,没有内部函数。我想在我的脚本中声明函数,使我的代码更易读和重用代码等。在MATLAB中本身并不困难,例如:

示例1:

function main()
  myfunc('goat');
end

function myfunc(x)
  fprintf(x);
end

我的问题是我有一个巨大的数据文件,希望只加载一次,这样在开发时可以重新运行代码而不用浪费时间重新加载数据。在当前框架下没有内部函数的大脚本中,这并不是问题。一种解决方案是拥有两个matlab脚本文件。一个用于加载数据,另一个用于调用函数。

但是,在上面的示例1中,真正的全局变量声明无法使用,我被迫每次运行脚本时都要加载巨大的文件。我想做的事情可以通过以下两个示例来展示:

示例2:

% Global variable
if ~exist('data',var) 
  data = load biigdatafile.mat;  %FAILS, outside function.
end

function main()
  myfunc('goat');
end

function myfunc(x)
  fprintf(x);
end

示例3:

function main()
  % Global variable
  if ~exist('data',var)
    global data;     % Is not really global after whole script is completed.
    data = load biigdatafile.mat;
  end
  myfunc('goat');
end

function myfunc(x)
  fprintf(x);
end

因此,我的问题是如何声明一个真正的全局变量,就像示例2一样,在其中加载我的数据一次以保留在工作区中,同时在一个脚本内调用我的函数?

3
确实是一个重复的代码块;请注意,你不需要将数据声明为全局变量。你可以将其作为输入传递给子函数。只要你不对数据进行写入操作,该数组就不会被复制,所以从内存方面来看,你是安全的。 - Jonas
3个回答

2

使用输入参数,这就是它们的作用

你可以只使用主函数的参数,将数据集加载到基础工作空间中一次,并将该数据集作为参数调用你的函数。如果任何子函数也使用该数据集,请将其传递。

function main(data)
    if nargin<1
        disp('hey, you forgot to supply the dataset!');
    end
    % do your stuff
    showData(data);
end

然后在基础工作区中:

Data = load('biigdatafile.mat');
main(Data);

使用持久化变量

persistent X Y ZXYZ 定义为仅在声明它们的函数中可见、但其值在函数调用之间在内存中保留的变量。 持久化变量类似于全局变量,因为 MATLAB 软件为两者创建永久性存储。 它们不同于全局变量,因为持久化变量仅在声明它们的函数中被识别。

所以您可以轻松使用:

function main()
    persistent data;
    if isempty(data)
        disp('loading dataset');
        data=load('biigdatafile.mat');
    end
    % do your stuff
    showData(data);
end

当你第一次在一个空白的基础工作区或清空函数上调用此函数时,数据集将被加载。下一次(当该函数没有被编辑时),数据集将已经/仍在内存中。

我通常在只使用一个数据集时这样做;每次加载数据集太麻烦了,而且在测试函数时,只需按F5更容易。



* 你可能会问,何时清除一个函数?

每当你清除或修改一个在内存中的函数时,MATLAB也会清除该函数声明的所有持续变量。要保留一个函数直到MATLAB退出,请使用mlock


0

这不是在Matlab中声明全局变量的重复。全局变量只能被所有函数访问,但当脚本完成时,全局变量就会消失,我需要再次将它们读入内存。

我需要的是将局部变量移动到基础工作区,然后在其他函数调用期间再次访问它。我实际上已经通过以下代码解决了这个问题

function main()
  try
    Data = evalin('base','Data'); % Move back from base workspace
    fprintf('Already loaded...\n');
  catch
    fprintf('Loading data...');
    data = load biigdatafile.mat;
    assignin('base', 'Data', Data); % Move to base workspace
    fprintf('Ok\n');
  end

  showDocID(Data{1});
end

function showData(Data)
  fprintf(['Data: "' Data '"\n']);
end

0
全局变量必须在使用它们的地方进行声明。只需将 global data 添加到需要它的任何位置,然后它就会起作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接