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