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

1,549 阅读3分钟

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

循环语句

循环语句通常用于遍历一个集合,或者重复执行若干指令,直到满足某个条件等等。 AviatorScript 支持 for 和 while 两种循环语句,分别介绍如下。

for 语句:遍历集合

for ... in 语句通常用于遍历一个集合,例如下面是遍历 0 到 9 的数字,并打印:

## examples/for_range1.av

for i in range(0, 10) {
  println(i);
}

打印出:

0
1
2
3
4
5
6
7
8
9

其中 range(start, end) 函数用于创建一个 [start, end) 区间的整数集合,在迭代过程中,将 i 绑定到集合中的每个元素上,然后执行 {...} 里的代码块。大括号也是必需的,不能因为代码块是单行语句而忽略,这跟 java 是不同的。

range 函数还可以接受第三个参数,表示递增的 step 大小(不传默认 step 就是 1),比如我们可以打印 0 到 9 之间的偶数:

## examples/for_range2.av

for i in range(0, 10, 2) {
  println(i);
}

打印:

0
2
4
6
8

for .. in 可以用于任何集合结构,比如数组、 java.util.List 、 java.util.Map 等等:

## examples/for_seq.av

let m = seq.map("a", 1, "b", 2, "c", 3);

for x in m {
  println(x.key + "=" + x.value);
}

let list = seq.list(1, 2, 3, 4, 5, 6, 7, 8, 9);

let sum = 0;
for x in list {
  sum = sum + x;
}

println("sum of list is "+ sum);

这里 m 是一个 HashMap ,通过 seq.map 函数创建,里面是三个键值对 a=1, b=2, c=3 ,我们也可以通过 for...in 语句来遍历,并且通过 x.key 和 x.value 来访问每一对的键值。

list 就是一个 1 到 9 整数组成的 List ,我们利用 for 语句迭代累计它们的和 sum 并打印。

最终输出:

a=1
b=2
c=3
sum of c is 45

关于 for 和集合 Sequence 的关系可以继续阅读第八章

索引和 KV 遍历

从 5.2.4 版本开始, for 语句还支持迭代遍历过程带上索引或者 key/value:

## examples/for_index_kv.av

let a = tuple(1, 2, 3, 4, 5, 6, 7, 8, 9);

for i, x in a {
  assert(i + 1 == x);
  p("a[#{i}] = #{x}");
}

let m = seq.map("a", 1, "b", 2, "c", 3);

for k, v in m {
  p("#{k} = #{v}");
  if k == "a" {
    assert(v == 1);
  }elsif k == 'b' {
    assert(v == 2);
  }elsif k == 'c' {
    assert(v == 3);
  }else {
    throw "should not happen";
  }
}

通过 key[index], value 的形式就可以带上索引或者 KV 对(仅限 Map 类型)来遍历,输出:

a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
a = 1
b = 2
c = 3
null

continue/break/retur

如果你想在执行代码块中途跳过剩余代码,继续下个迭代,可以用 continue ,比如下面的示例,跳过所有偶数,也就是打印奇数:

## examples/for_continue.av

for i in range(0, 10) {
  if i % 2 == 0 {
    continue;
  }
  println(i);
}

同样,如果想中途跳出迭代,你可以用 break:

## examples/for_break.av

for i in range(0, 10) {
  if i > 5 {
    break;
  }
  println(i);
}

当 i 大于 5 的时候,我们就跳出循环,因此只打印了:

0
1
2
3
4
5

return 有类似 break 的效果,也可以从循环中跳出,但是它会将整个脚本(或者函数)中断执行并返回,而不仅仅是跳出循环:

## examples/for_return.av

for i in range(0, 10) {
  if i > 5 {
    return;
  }
  println(i);
}

println("Can't reach here");

当 i 大于 5 的时候,我们就直接返回了, for 循环之后的代码也不会执行,因此也不会打印 Can't reach here 。

while 语句

while 循环本质上是条件语句和循环的结合,当满足一定条件下,不停地执行一段代码块,直到条件变为否定:

## examples/while1.av

let sum = 1;

while sum < 1000 {
  sum = sum + sum;
}

println(sum);

sum 从  1 开始,不停地累加自身,直到超过 1000 才终止,这里输出:

1024

while 后面跟 if 一样跟着一个布尔表达式,括号同样可以省略,但是代码块必须用大括号包围起来,这跟 if/for 也是一样的。

同样, while 也可以用 break 和 continue 语句,比如上面的例子我们可以改写成:

## examples/while2.av

let sum = 1;

while true {
  sum = sum + sum;
  if sum > 1000 {
    break;
  }
}

println(sum);

使用 while true  来无限循环,直到 sum 大于 1000 就 break 跳出。

return/continue 的使用和 for 类似,不再赘述。

循环语句也可以多层嵌套,这跟其他语言都没有什么两样:

let c = 0;
for i in range(0, 10) {
  for j in range(0, 10) {
    c =  c + i * j;
  }
}
println(c);