表達(dá)式和語(yǔ)句的區(qū)別:
- 表達(dá)式有值,語(yǔ)句沒(méi)有值, 能作為函數(shù)參數(shù)即為表達(dá)式,否則為語(yǔ)句。
- C語(yǔ)言中的控制結(jié)構(gòu)為語(yǔ)句。
- 函數(shù)式語(yǔ)言中的所有東西都有值, 都是表達(dá)式
If表達(dá)式
在 Kotlin 中, if 是一個(gè)表達(dá)式,即它會(huì)返回一個(gè)值。 因此就不需要三元運(yùn)算符(條件 ? 然后 : 否則),因?yàn)槠胀ǖ? if 就能勝任這個(gè)角色。
// 傳統(tǒng)用法
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作為表達(dá)式
val max = if (a > b) a else b
//if 的分支可以是代碼塊,最后的表達(dá)式作為該塊的值:
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
如果你使用 if 作為表達(dá)式而不是語(yǔ)句,該表達(dá)式需要有 else 分支。
When 表達(dá)式
when 取代了java 語(yǔ)言的 switch。其最簡(jiǎn)單的形式如下:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意這個(gè)塊
print("x is neither 1 nor 2")
}
}
when將它的參數(shù)和所有的分支條件順序比較,直到某個(gè)分支滿足條件。 when 既可以做表達(dá)式也可以做語(yǔ)句使用。如果它做表達(dá)式, 符合條件的分支的值就是整個(gè)表達(dá)式的值,如果當(dāng)做語(yǔ)句使用, 則忽略個(gè)別分支的值.
如果其他分支都不滿足條件將會(huì)求值 else 分支。 如果 when 作為一個(gè)表達(dá)式使用,則必須有 else 分支, 除非編譯器能夠檢測(cè)出所有的可能情況都已經(jīng)覆蓋了。
- 如果很多分支需要用相同的方式處理,則可以把多個(gè)分支條件放在一起,用逗號(hào)分隔:
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
- 我們可以用任意表達(dá)式(而不只是常量)作為分支條件
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
- 我們也可以檢測(cè)一個(gè)值在( in )或者不在( !in )一個(gè)區(qū)間或者集合中:
when (x) {
in 1..10 -> print("x在范圍內(nèi)")
in validNumbers -> print("x有效")
!in 10..20 -> print("x在范圍外")
else -> print("以上都不是")
}
- 另一種可能性是檢測(cè)一個(gè)值是( is )或者不是( !is )一個(gè)特定類(lèi)型的值。注意: 由于智能轉(zhuǎn)換,你可以訪問(wèn)該類(lèi)型的方法和屬性而無(wú)需任何額外的檢測(cè)。
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
- when 也可以用來(lái)取代 if - else if 鏈。 如果不提供參數(shù),所有的分支條件都是簡(jiǎn)單的布爾表達(dá)式,而當(dāng)一個(gè)分支的條件為真時(shí)則執(zhí)行該分支:
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
For 循環(huán)
for 循環(huán)可以對(duì)任何提供迭代器(iterator)的對(duì)象進(jìn)行遍歷,語(yǔ)法如下:
for (item in collection) print(item)
循環(huán)體可以是一個(gè)代碼塊。
for (item: Int in ints) {
// ……
}
如上所述, for 可以循環(huán)遍歷任何提供了迭代器的對(duì)象。即:
有一個(gè)成員函數(shù)或者擴(kuò)展函數(shù) iterator() ,它的返回類(lèi)型
有一個(gè)成員函數(shù)或者擴(kuò)展函數(shù) next() ,并且
有一個(gè)成員函數(shù)或者擴(kuò)展函數(shù) hasNext() 返回 Boolean 。
這三個(gè)函數(shù)都需要標(biāo)記為 operator 。
對(duì)數(shù)組的 for 循環(huán)會(huì)被編譯為并不創(chuàng)建迭代器的基于索引的循環(huán)。
如果你想要通過(guò)索引遍歷一個(gè)數(shù)組或者一個(gè) list,你可以這么做:
for (i in array.indices) {
print(array[i])
}
注意這種“在區(qū)間上遍歷”會(huì)編譯成優(yōu)化的實(shí)現(xiàn)而不會(huì)創(chuàng)建額外對(duì)象。
或者你可以用庫(kù)函數(shù) withIndex
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
While 循環(huán)
while 和 do .. while 照常使用
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此處可見(jiàn)
返回與跳轉(zhuǎn)(Returns and Jumps)
Kotlin支持三種跳轉(zhuǎn)操作符
- return,結(jié)束最近的閉合循環(huán)
- break,跳出最近的閉合循環(huán)
- continue,跳到最近的閉合循環(huán)的下一次循環(huán)
break和continue標(biāo)簽(Break and Continue Labels)
Kotlin中的任何表達(dá)式都可以用標(biāo)簽標(biāo)記,標(biāo)簽是后面加@符號(hào)的標(biāo)識(shí)符的形式,例如:abc @,fooBar @
。
loop@ for (i in 1..100){ // loop@就是標(biāo)簽
//...
}
使用break 跳轉(zhuǎn)到標(biāo)簽處,跳出循環(huán)
loop@ for (i in 1..10) {
for (j in i..10) {
if (j == 5)
break@loop // 跳出循環(huán)
Log.e(Tag, j.toString()) // j 為5的時(shí)候跳出了循環(huán),只打印1、2、3、4
}
}
使用continue跳轉(zhuǎn)到標(biāo)簽處,進(jìn)行下一次循環(huán)
loop@ for (i in 1..10) {
for (j in i..10) {
if (j == 5)
continue@loop // 跳出本次循環(huán),進(jìn)行下一次循環(huán)
Log.e(Tag, j.toString()) // j 為5的時(shí)候跳出了循環(huán),所有不會(huì)打印5
}
}
return標(biāo)簽(Return at Labels)
在字面函數(shù),局部函數(shù),以及對(duì)象表達(dá)式中,函數(shù)可以在 Kotlin 中被包裹。return允許返回到外層函數(shù)。
fun foo() {
ints.forEach {
if (it == 0) return // 跳出forEach
print(it)
}
}
return表達(dá)式返回到最近的閉合函數(shù)(foo()
)
fun foo() {
ints.forEach lit@ {
it (it ==0) return@lit
// 這樣就不會(huì)return到foo函數(shù),而是return到標(biāo)簽處的forEach函數(shù)
print(it)
}
}
通常這種情況用一種更方便的標(biāo)簽,例如用一個(gè)和傳入的 Lambda 表達(dá)式名字相同的標(biāo)簽。
fun foo() {
ints.forEach {
if (it ==0) return@forEach
// 與上面一樣,return到標(biāo)簽處的forEach函數(shù)
print(it)
}
}
另外,可以用匿名函數(shù)替換lambda表達(dá)式,使用 return 語(yǔ)句可以從匿名函數(shù)中返回
fun foo() {
ints.forEach(fun(value: Int){
if (value == 0) return
print(value)
})
}
當(dāng)要返一個(gè)回值的時(shí)候,解析器優(yōu)先選用標(biāo)簽限制的 return,即
return@a 1
意為“從標(biāo)簽 @a 返回 1”,而不是“返回一個(gè)標(biāo)簽標(biāo)注的表達(dá)式 (@a 1) ”。