7.2 持久变量

另请参阅关键字:persistent

在函数内部被声明为 persistent(持久) 的变量,会在对该函数的多次调用之间将其内容保留在内存中。持久变量与全局变量的区别在于:持久变量的作用域局限于特定函数内部,在其他地方不可见。

以下示例使用持久变量创建了一个函数,该函数会打印自身被调用的次数。

function count_calls ()
  persistent calls = 0;
  printf ("'count_calls' has been called %d times\n",
          ++calls);
endfunction

for i = 1:3
  count_calls ();
endfor

-| 'count_calls' has been called 1 times
-| 'count_calls' has been called 2 times
-| 'count_calls' has been called 3 times

如示例所示,可以使用 persistent 声明语句将变量声明为持久变量。以下语句都是持久变量的声明方式。

persistent a
persistent a b
persistent c = 2
persistent d = 3 e f = 5

持久变量的行为与 C 语言中的静态变量(static variable)等价。

持久变量有一个限制:函数的输入参数和输出参数都不能声明为持久变量:

function y = foo ()
  persistent y = 0;  # 不允许!
endfunction

foo ()
-| error: can't make function parameter y persistent

与全局变量一样,持久变量只能被初始化一次。例如,执行以下代码之后:

persistent pvar = 1
persistent pvar = 2

持久变量 pvar 的值为 1,而不是 2。

如果一个持久变量被声明但未初始化为特定值,它将包含一个空矩阵。因此,也可以通过检查持久变量是否为空来对其进行初始化,如下例所示。

function count_calls ()
  persistent calls;
  if (isempty (calls))
    calls = 0;
  endif
  printf ("'count_calls' has been called %d times\n",
          ++calls);
endfunction

该实现的行为方式与前面 count_calls 的实现完全相同。

持久变量的值会一直保留在内存中,直到被显式清除。假设 count_calls 的实现保存在磁盘上,则会出现以下行为:

for i = 1:2
  count_calls ();
endfor
-| 'count_calls' has been called 1 times
-| 'count_calls' has been called 2 times

clear
for i = 1:2
  count_calls ();
endfor
-| 'count_calls' has been called 3 times
-| 'count_calls' has been called 4 times

clear all
for i = 1:2
  count_calls ();
endfor
-| 'count_calls' has been called 1 times
-| 'count_calls' has been called 2 times

clear count_calls
for i = 1:2
  count_calls ();
endfor
-| 'count_calls' has been called 1 times
-| 'count_calls' has been called 2 times

也就是说,只有当包含该变量的函数被移除时,持久变量才会从内存中删除。请注意,如果函数定义是直接输入到 Octave 提示符中的,那么仅需一个简单的 clear 命令就会清除该持久变量,因为整个函数定义都将从内存中移除。如果希望在函数被清除后持久变量仍然保留在内存中,则应使用 mlock 函数(参见 函数锁定)。


版权所有 © 2024-2026 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-2