# 流控制
## If 表達式
Kotlin 中的 `if` 是一個表達式,意即它會返回一個值。因此沒有三目運算符,因為普通的 `if` 就能很好地擔任這個角色。
``` kotlin
// 傳統用法
var max = a
if (a < b)
max = b
// 加上 else
var max: Int
if (a > b)
max = a
else
max = b
// 與表達式一樣
val max = if (a > b) a else b
```
`if` 分支可以是塊,并且一個塊中最后的表達式就是值:
``` kotlin
val max = if (a > b) {
print("Choose a")
a
}
else {
print("Choose b")
b
}
```
如果你把 `if` 當成一個表達式而不是指令(例如,返回它的值或把它賦值給一個變量),那么這個表達式必須要有一個 `else` 分支。
查看 [grammar for *if*{: .keyword }](grammar.html#if)
## When 表達式
`when` 代替了類 C 語言中的 switch。最簡單的形式類似這樣
``` kotlin
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意這個塊
print("x is neither 1 nor 2")
}
}
```
`when` 匹配它的所有的參量分支直到一些分支滿足條件。`when` 可以作為表達式或指令使用。如果它作為表達式使用,滿足的分支的值則成為整個表達式的值。如果作為指令使用,單獨分支的值則被忽略(和 `if` 類似,每個分支都可以是一個塊,并且值就是最后表達式的值)。
如果其它的分支都沒有滿足條件則 `else` 分支就會被求值。如果 `when` 作為表達式使用,那么 `else` 是強制的,除非編譯器能證明分支條件覆蓋了所有的可能性。
如果一些條件應該以同樣的方式處理,那么這個分支條件可以以一個逗號合并:
``` kotlin
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
```
我們可以使用任意表達式(不僅僅是常量)作為分支條件
``` kotlin
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
```
我們還能檢查一個值 `in` 或者 `!in` 在某個[范圍](ranges.html)或某個集合內:
``` kotlin
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
```
其它的可能性是要檢查一個值 `is` 或 `!is` 某個類型。注意,由于[智能轉換](typecasts.html#smart-casts),你不用額外的檢查就可以訪問這個類型的方法和屬性。
```kotlin
val hasPrefix = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
```
`when` 還能作為 `if-else if` 鏈條的替代。如果沒有參量給出,則分支條件就是簡單的布爾表達式,并且一個分支是在它的條件為 `true` 時執行:
``` kotlin
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
```
查看 [grammar for *when*{: .keyword }](grammar.html#when).
## For 循環
`for` 循環通過提供的迭代器迭代任何東西。語法像下面這樣:
``` kotlin
for (item in collection)
print(item)
```
循環體可以是一個塊。
``` kotlin
for (item: Int in ints) {
// ...
}
```
就像前面所說的,`for` 通過提供的迭代器迭代任何東西,也就是說:
* 有一個成員或擴展的 `iterator()` 函數所返回的類型
* 有一個成員或擴展的 `next()` 函數,并且
* 有一個成員或擴展的 `hasNext()` 函數返回 `Boolean`。
這三個函數都要標記為 `operator`。
數組上的 `for` 循環被編譯成一個基于索引的循環,不會創建一個迭代器對象。
如果你要用一個索引迭代一個數組或一個列表,你可以用這種方法實現:
``` kotlin
for (i in array.indices)
print(array[i])
```
注意“迭代某個范圍”會被編譯為優化實現,沒有額外的對象創建。
另外,你可以使用 `withIndex` 庫函數:
``` kotlin
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
```
查看 [grammar for *for*{: .keyword }](grammar.html#for).
## While 循環
*while*{: .keyword } 和 *do*{: .keyword }..*while*{: .keyword } 工作和通常的一樣
``` kotlin
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在這里是可見的!
```
查看 [grammar for *while*{: .keyword }](grammar.html#while).
## 循環中的 Break 和 continue
Kotlin 支持循環中傳統的 `bread` 和 `continue` 操作符。查看 [Returns and jumps](returns.html)