条件语句的值

在 AviatorScript 中,每个语句都有一个值,而不仅仅是整个脚本(参见 3.6 节 多行表达式和 return)。比如 if 条件语句也有一个值,就是实际执行的分支语句的结果

  1. ## examples/statement_value.av
  2. let a = if (true) {
  3. 1
  4. };
  5. p("a is :" + type(a) +", " + a);

输出:

  1. a is :long, 1

因为条件判断为 true ,所以执行了大括号中的分支语句,按照规则,连续的多行表达式,返回最后一个表达式的值,这里就是 1 ,整个分支语句的结果就是 1 ,因此整个 if 语句的结果也是 1 ,我们赋值给了 a ,并打印类型和值。 注意到 if 语句最后的分号 ; ,它是用来结束赋值语句,将条件表达式的结果赋值给了 a,如果没有将报错:

  1. Exception in thread "main" com.googlecode.aviator.exception.ExpressionSyntaxErrorException:
  2. Syntax error: missing ';' for let statement at 92, lineNumber: 8, token : null,
  3. while parsing expression: `
  4. ## examples/statement_value.av
  5. let a = if (true) {
  6. 1
  7. }
  8. p("a is :" + type(a) +", " + a);
  9. ^^^
  10. `
  11. at com.googlecode.aviator.AviatorEvaluatorInstance.innerCompile(AviatorEvaluatorInstance.java:1293)
  12. at com.googlecode.aviator.AviatorEvaluatorInstance.compile(AviatorEvaluatorInstance.java:1256)

如果我们将条件判断该为 false 呢?:

  1. let a = if (false) {
  2. 1
  3. };
  4. p("a is :" + type(a) +", " + a);

执行输出:

  1. a is :nil, null

因为没有 else 分支,默认值就是 nil ,整个 if 条件语句的结果也是 nil

我们加上 else 分支试试:

  1. let a = if (false) {
  2. 1
  3. } else {
  4. 2
  5. };
  6. p("a is :" + type(a) +", " + a);

这时候结果就是 2 了:

  1. a is :long, 2

循环语句的值

事实上不仅是条件语句, for/while 循环语句也有值:

  1. let b = for x in range(0, 10) {
  2. x
  3. };
  4. p("b is :" + type(b) +", " + b);

循环语句的结果是最后一次迭代过程中返回的值,因此这里是最后一次迭代 x 的值,也就是 9

  1. b is :long, 9

如果加上 break/continue 呢?:

  1. let b = for x in range(0, 10) {
  2. if x == 2 {
  3. break;
  4. }
  5. };
  6. p("b is :" + type(b) +", " + b);

因为最后一次迭代执行的是 break 或者 continue 的时候,结果都将是 nil

  1. b is :nil, null

但是如果是 return 呢?情况又不一样,如果最后一次迭代返回结果是 return,那么整个循环语句的结果就是 return 的结果,这跟 3.6 节的规则是一样的更一般地,如果整个语句的返回结果是 return 的结果,并且赋值给了一个变量,那么这个 return 将只是从该语句中返回,而不是从整个脚本返回

  1. let b = for x in range(0, 10) {
  2. if x == 2 {
  3. return x;
  4. }
  5. };
  6. p("b is :" + type(b) +", " + b);

我们在循环语句中调用了 return 2; ,但是它不会从整个脚本中返回(否则下面的打印将无法执行),而只是从循环语句中返回,并将结果赋值给了 b:

  1. b is :long, 2

块(Block)的值

通过大括号括起来的一个块也有一个值,就是这个块里最后一个执行的表达式的值:

  1. ## Block's value
  2. let c = {
  3. let a = 1;
  4. let b = 2;
  5. a + b
  6. };
  7. p("c is :" + type(c) +", " + c);

执行输出:

  1. c is :long, 3

return 也是一样,如果将块的赋值给了某个变量,那就将从块里返回:

  1. let c = {
  2. let a = 1;
  3. let b = 2;
  4. if a > b {
  5. return a;
  6. } else {
  7. return b;
  8. }
  9. };
  10. p("c is :" + type(c) +", " + c);

执行结果将是块里的局部变量 b 的值:

  1. c is :long, 2