一个变量有它的作用域,比如简单的:
## 全局作用域let a = 1;a = a + 1;println(a);
a 的作用域在 let 定义后,在整个脚本内有效,我们称之为全局作用域,在这个范围内,你可以正常地读写它。
但是你可以限定一个变量的作用域,通过大括号来引入一个嵌套的作用域:
## examples/scope1.avlet a = 1; ## 全局作用域内的 a{## 嵌套作用域 scope1let a = 2; ## let 定义了 scope1 内有效的变量 aprintln(a); ##打印 scope1 内的 aa = 3; ##给 scope1 的变量 a 赋值}println(a); ## 打印全局作用域的 a
上面的代码将打印:
21
首先打印嵌套作用域内的定义的 a ,它在里面被赋值为 2,嵌套作用域内的 a “掩盖” 了全局作用域定义的 a 变量,在离开嵌套作用域后,继续打印了全局作用域的变量 a ,它的值仍然是 1。
如果你有其他语言的经验,这个概念还是很好的理解的。这里 scope1 作用域和全局作用域形成了父子关系, scope1 的父作用域是全局作用域,我们通过 let 定义的 a 仅在 scope1 内有效。
let 语句
let 语句就是让你在特定作用域内定义一个变量,如果父作用域有同名的变量,将“掩盖”父作用域的变量。如果不使用 let ,你读写的将仍然是父作用域的变量:
## examples/scope2.avlet a = 1; ## 全局作用域内的 a{## 嵌套作用域 scope1a = 2; ## 不适用 let,访问的还是全局作用域的变量 aprintln(a); ##打印 scope1 内的 aa = 3; ##给全局作用域的变量 a 赋值}println(a); ## 打印全局作用域的 a
去掉 let 之后,打印结果为:
23
全局作用域的变量 a 在 scope1 内被修改成了 3。
嵌套作用域
作用域还可以继续深层嵌套,遵循的规则不变:
let定义当前作用域的变量,这些变量同时可以被它的子作用域访问和修改,离开当前作用域后不可触达。let定义的变量将“掩盖”父作用域的同名变量。- 子作用域可以访问和修改父作用域定义的变量,离开子作用域后修改继续生效。
稍微复杂点的例子:
## examples/scope3.av## examples/scope3.avlet a = 1;{a = 2;let a = 3;b = 4;{a = 5;b = 6;let c = 7;println("a in scope2:" + a);println("b in scope2:" + b);println("c in scope2:" + c);}println("a in scope1:" + a);println("b in scope1:" + b);println("c in scope1:" + c);}println("a in global scope:" + a);println("b in global scope:" + b);println("c in global scope:" + c);
打印出:
a in scope2:5b in scope2:6c in scope2:7a in scope1:5b in scope1:6c in scope1:nulla in global scope:2b in global scope:nullc in global scope:null
可以仔细阅读下这个代码和输出,整个规则还是比较容易理解的。
