# when表达式

when表达式是ZGG提供的一种比常见的三目运算符更为强大的条件选择表达式。when表达式有两种形式：

* 无值形式
* 有值形式

## 无值形式

用法为：

```
when {
    条件1 -> 返回值1
    条件2 -> 返回值2
    ...
    条件n -> 返回值n
    else -> else返回值
}
```

“条件->值”至少要有一个，else部分可以缺省

表达式求值时，会依次执行条件判断的表达式，如果返回真值，则该when表达式返回对应的返回值。后续的条件表达式和返回值表达式不会被求值。如果返回假值，则继续执行下一个条件。

如果所有条件都为假值，这时候：

1. 如果有设else部分，则返回else对应的返回值
2. 如果没有设else部分，则返回undefined

### 无值形式例子

```
when {
    user.age >= 60 -> '老人'
    user.age < 10  -> '小孩'
    user.isMale()  -> '男士'
    else           -> '女士'
}
```

***

## 有值形式

用法为：

```
when 待判断的值 {
    范围1 -> 返回值1
    范围2 -> 返回值2
    ...
    范围n -> 返回值n
    else -> else返回值
}
```

“范围->值”至少要有一个，else部分可以缺省

表达式求值的流程为：

1. 先对待判断的值的表达式进行求值
2. 依次判断上述值是否属于指定范围，如果是，返回对应的返回值
3. 如果所有范围都不命中，那么：
   1. 如果有指定else，返回else对应返回值
   2. 如果没有指定else，返回undefined

### 范围表达式

when表达式的有值形式，使用了一种特定的范围表达方式。

* 离散集合：

形式为：value1, value2, ..., valueN

当且仅当待判断值跟任意一个value相等时为真

* 区间
  * 闭区间: a..b
    * 当且仅当value >= a && value <= b时为真
  * 前闭后开区间: a..\<b
    * 当且仅当value >= a && value < b时为真
  * 小于: ..\<b
    * 当且仅当value < b时为真
  * 小于等于: ..b
    * 当且仅当value <= b时为真
  * 大于等于: a..
    * 当且仅当value >= a时为真
* 类型判断

形式为：is TypeName

### 有值形式例子

```
// 求斐波拉切数
fib := n => when n  {
    1, 2 -> 1
    3..  -> fib(n-1) + fib(n-2)
    else -> 0
}

foo := v => println(v, when v {
    is Float -> '是浮点型'
    is Bool  -> '是布尔型'
    is @time.Time -> '是时间类型'
    is SomeCustomClass -> '是某个自定义的类型'
    'a', 'b'  -> '不是a就是b'
    1..10 -> '在1到10之间'
    else  -> '不知道是啥'
})
```
