条件语句的值
在 AviatorScript 中,每个语句都有一个值,而不仅仅是整个脚本(参见 3.6 节 多行表达式和 return)。比如 if 条件语句也有一个值,就是实际执行的分支语句的结果:
## examples/statement_value.av
let a = if (true) {
1
};
p("a is :" + type(a) +", " + a);
输出:
a is :long, 1
因为条件判断为 true
,所以执行了大括号中的分支语句,按照规则,连续的多行表达式,返回最后一个表达式的值,这里就是 1
,整个分支语句的结果就是 1
,因此整个 if 语句的结果也是 1
,我们赋值给了 a
,并打印类型和值。 注意到 if 语句最后的分号 ;
,它是用来结束赋值语句,将条件表达式的结果赋值给了 a,如果没有将报错:
Exception in thread "main" com.googlecode.aviator.exception.ExpressionSyntaxErrorException:
Syntax error: missing ';' for let statement at 92, lineNumber: 8, token : null,
while parsing expression: `
## examples/statement_value.av
let a = if (true) {
1
}
p("a is :" + type(a) +", " + a);
^^^
`
at com.googlecode.aviator.AviatorEvaluatorInstance.innerCompile(AviatorEvaluatorInstance.java:1293)
at com.googlecode.aviator.AviatorEvaluatorInstance.compile(AviatorEvaluatorInstance.java:1256)
如果我们将条件判断该为 false 呢?:
let a = if (false) {
1
};
p("a is :" + type(a) +", " + a);
执行输出:
a is :nil, null
因为没有 else 分支,默认值就是 nil
,整个 if 条件语句的结果也是 nil
。
我们加上 else
分支试试:
let a = if (false) {
1
} else {
2
};
p("a is :" + type(a) +", " + a);
这时候结果就是 2 了:
a is :long, 2
循环语句的值
事实上不仅是条件语句, for/while 循环语句也有值:
let b = for x in range(0, 10) {
x
};
p("b is :" + type(b) +", " + b);
循环语句的结果是最后一次迭代过程中返回的值,因此这里是最后一次迭代 x 的值,也就是 9
:
b is :long, 9
如果加上 break/continue 呢?:
let b = for x in range(0, 10) {
if x == 2 {
break;
}
};
p("b is :" + type(b) +", " + b);
因为最后一次迭代执行的是 break 或者 continue 的时候,结果都将是 nil
:
b is :nil, null
但是如果是 return
呢?情况又不一样,如果最后一次迭代返回结果是 return,那么整个循环语句的结果就是 return 的结果,这跟 3.6 节的规则是一样的。更一般地,如果整个语句的返回结果是 return 的结果,并且赋值给了一个变量,那么这个 return 将只是从该语句中返回,而不是从整个脚本返回:
let b = for x in range(0, 10) {
if x == 2 {
return x;
}
};
p("b is :" + type(b) +", " + b);
我们在循环语句中调用了 return 2;
,但是它不会从整个脚本中返回(否则下面的打印将无法执行),而只是从循环语句中返回,并将结果赋值给了 b:
b is :long, 2
块(Block)的值
通过大括号括起来的一个块也有一个值,就是这个块里最后一个执行的表达式的值:
## Block's value
let c = {
let a = 1;
let b = 2;
a + b
};
p("c is :" + type(c) +", " + c);
执行输出:
c is :long, 3
return 也是一样,如果将块的赋值给了某个变量,那就将从块里返回:
let c = {
let a = 1;
let b = 2;
if a > b {
return a;
} else {
return b;
}
};
p("c is :" + type(c) +", " + c);
执行结果将是块里的局部变量 b
的值:
c is :long, 2