嵌套函数与子函数类似,都是只有主函数在文件外部可见。但嵌套函数还允许子函数访问其父函数中的局部变量。这种共享访问模拟了使用全局变量来共享信息——但这个全局变量对 Octave 的其他部分不可见。作为一种编程策略,以这种方式共享数据可能会导致代码难以维护。建议尽可能使用子函数来代替嵌套函数。
作为一个简单示例,考虑一个父函数 foo,它调用了一个嵌套的子函数 bar,并共享变量 x。
function y = foo ()
x = 10;
bar ();
y = x;
function bar ()
x = 20;
endfunction
endfunction
foo ()
⇒ 20
请注意,共享 x 并没有特殊的语法。这可能导致父函数与其子函数之间意外地共享变量。虽然变量通常是继承的,但子函数的参数和返回值属于子函数的局部变量。
现在考虑函数 foobar,它使用了变量 x 和 y。foobar 调用嵌套函数 foo,该函数以 x 为参数并返回 y。foo 又调用了 bat,后者进行一些计算。
function z = foobar ()
x = 0;
y = 0;
z = foo (5);
z += x + y;
function y = foo (x)
y = x + bat ();
function z = bat ()
z = x;
endfunction
endfunction
endfunction
foobar ()
⇒ 10
需要注意的是,foobar 中的 x 和 y 仍然保持为零,因为在 foo 中它们分别是返回值 和 参数。bat 中的 x 指的是 foo 中的 x。
变量继承给 eval 和脚本带来了问题。如果在父函数中创建了一个新变量,嵌套子函数中应该发生什么就不明确了。例如,考虑一个父函数 foo 及其嵌套的子函数 bar:
function y = foo (to_eval)
bar ();
eval (to_eval);
function bar ()
eval ("x = 100;");
eval ("y = x;");
endfunction
endfunction
foo ("x = 5;")
⇒ error: can not add variable "x" to a static workspace
foo ("y = 10;")
⇒ 10
foo ("")
⇒ 100
父函数 foo 无法创建新变量 x,但子函数 bar 却成功了。此外,即使在 eval 语句中,bar 中的 y 与其父函数 foo 中的 y 也是同一个变量。最好避免将 eval 与嵌套函数结合使用。
与子函数一样,只有文件中的第一个嵌套函数可以从外部调用。在函数内部,规则更为复杂。一般来说,一个嵌套函数可以调用:
作为一个复杂示例,考虑一个父函数 ex_top,它有两个子函数 ex_a 和 ex_b。此外,ex_a 还有两个子函数 ex_aa 和 ex_ab。例如:
function ex_top ()
## 可以调用:ex_top、ex_a 和 ex_b
## 不能调用:ex_aa 和 ex_ab
function ex_a ()
## 可以调用所有函数
function ex_aa ()
## 可以调用所有函数
endfunction
function ex_ab ()
## 可以调用所有函数
endfunction
endfunction
function ex_b ()
## 可以调用:ex_top、ex_a 和 ex_b
## 不能调用:ex_aa 和 ex_ab
endfunction
endfunction
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-4