Java使用Aviator表达式 学习记录(六)

811 阅读3分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

作用域

一个变量有它的作用域,比如简单的:

## 全局作用域
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。

嵌套作用域

作用域还可以继续深层嵌套,遵循的规则不变:

  1. let 定义当前作用域的变量,这些变量同时可以被它的子作用域访问和修改,离开当前作用域后不可触达。
  2. let 定义的变量将“掩盖”父作用域的同名变量。
  1. 子作用域可以访问和修改父作用域定义的变量,离开子作用域后修改继续生效。

稍微复杂点的例子:

## 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