9.2 不同上下文中的求值

在求值表达式之前,需要替换表达式中使用的变量的值。这些值存储在符号表中。每当解释器启动一个新函数时,它都会保存当前的符号表并创建一个新的符号表,然后用函数参数列表以及一些预定义变量(例如 nargin)对其进行初始化。函数内部的表达式使用新的符号表。

有时你可能想编写这样一个函数:当你调用它时,它会在你自身的上下文中修改变量。这允许你使用按名称传递(pass-by-name)风格的函数,类似于在 C 等编程语言中使用指针。

考虑如何以 m 文件形式编写 saveload。例如:

function create_data
  x = linspace (0, 10, 10);
  y = sin (x);
  save mydata x y
endfunction

借助 evalin,你可以将 save 编写如下:

function save (file, name1, name2)
  f = open_save_file (file);
  save_var (f, name1, evalin ("caller", name1));
  save_var (f, name2, evalin ("caller", name2));
endfunction

这里,callercreate_data 函数,name1 是字符串 "x",它被简单地求值为 x 的值。

稍后,你希望在另一个上下文中从 mydata 加载回这些值:

function process_data
  load mydata
  ... do work ...
endfunction

借助 assignin,你可以将 load 编写如下:

function load (file)
  f = open_load_file (file);
  [name, val] = load_var (f);
  assignin ("caller", name, val);
  [name, val] = load_var (f);
  assignin ("caller", name, val);
endfunction

这里,callerprocess_data 函数。

你可以在命令提示符下使用上下文 base(而非 caller)来设置和使用变量。

这些函数在实践中很少使用。一个例子是 fail ('code', 'pattern') 函数,它在调用者的上下文中求值 code,并检查它产生的错误消息是否与给定的模式匹配。其他示例(如 saveload)是用 C++ 编写的,其中所有 Octave 变量都在 caller 上下文中,因此不需要 evalin

 
evalin (context, try)
evalin (context, try, catch)
[var1, …] = evalin (…)

eval 类似,区别在于表达式在指定的上下文 context 中求值,context 可以是 "caller""base"

另请参阅: evalassignin

 
assignin (context, varname, value)

在上下文 context 中将 value 赋值给 varnamecontext 可以是 "base""caller"

另请参阅: evalin


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

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