在求值表达式之前,需要替换表达式中使用的变量的值。这些值存储在符号表中。每当解释器启动一个新函数时,它都会保存当前的符号表并创建一个新的符号表,然后用函数参数列表以及一些预定义变量(例如 nargin)对其进行初始化。函数内部的表达式使用新的符号表。
有时你可能想编写这样一个函数:当你调用它时,它会在你自身的上下文中修改变量。这允许你使用按名称传递(pass-by-name)风格的函数,类似于在 C 等编程语言中使用指针。
考虑如何以 m 文件形式编写 save 和 load。例如:
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
这里,caller 是 create_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
这里,caller 是 process_data 函数。
你可以在命令提示符下使用上下文 base(而非 caller)来设置和使用变量。
这些函数在实践中很少使用。一个例子是 fail ('code', 'pattern') 函数,它在调用者的上下文中求值 code,并检查它产生的错误消息是否与给定的模式匹配。其他示例(如 save 和 load)是用 C++ 编写的,其中所有 Octave 变量都在 caller 上下文中,因此不需要 evalin。
(context, try) ¶(context, try, catch) ¶[var1, …] = evalin (…) ¶与 eval 类似,区别在于表达式在指定的上下文 context 中求值,context 可以是 "caller" 或 "base"。
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-4