For 循環(huán)
for 循環(huán)可以對(duì)任何提供迭代器(iterator)的對(duì)象進(jìn)行遍歷,語法如下:
for (item in collection) print(item)
循環(huán)體可以是一個(gè)代碼塊:
for (item: Int in ints) {
// ……
}
如上所述,for 可以循環(huán)遍歷任何提供了迭代器的對(duì)象。
如果你想要通過索引遍歷一個(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 與 do...while 循環(huán)
do…while 循環(huán)和 while 循環(huán)相似,不同的是,do…while 循環(huán)至少會(huì)執(zhí)行一次,而while如果條件不符合,則一次都不進(jìn)入
while( 布爾表達(dá)式 ) {
//循環(huán)內(nèi)容
}
do {
//代碼語句
}while(布爾表達(dá)式);
示例
tvContent.append("----while 使用-----")
tvContent.append("\n")
var x = 5
while (x > 0) {
tvContent.append(x--.toString())
}
tvContent.append("----do...while 使用-----")
tvContent.append("\n")
var y = 5
do {
tvContent.append(y--.toString())
} while(y>0)
返回和跳轉(zhuǎn)
Kotlin 跟java一樣有三種結(jié)構(gòu)化跳轉(zhuǎn)表達(dá)式:
- return。默認(rèn)從最直接包圍它的函數(shù)或者匿名函數(shù)返回。
- break。終止最直接包圍它的循環(huán)。
- continue。繼續(xù)下一次最直接包圍它的循環(huán)。
在循環(huán)中 Kotlin 支持傳統(tǒng)的 break 和 continue 操作符。
tvContent.append("\n(不使用標(biāo)簽):")
for (i in 1..10) {
if (i == 3) continue // i 為 3 時(shí)跳過當(dāng)前循環(huán),繼續(xù)下一次循環(huán)
tvContent.append(i.toString())
if (i > 5) break // i 為 6 時(shí) 跳出循環(huán)
}
Break 和 Continue 標(biāo)簽
在 Kotlin 中任何表達(dá)式都可以用標(biāo)簽(label)來標(biāo)記。 標(biāo)簽的格式為標(biāo)識(shí)符后跟 @ 符號(hào),例如:abc@、fooBar@都是有效的標(biāo)簽。 要為一個(gè)表達(dá)式加標(biāo)簽,我們只要在其前加標(biāo)簽即可。
loop@ for (i in 1..100) {
// ……
}
現(xiàn)在,我們可以用標(biāo)簽限制 break 或者continue:
// 標(biāo)簽式標(biāo)記,@loop結(jié)束后就返回對(duì)應(yīng)的@loop
tvContent.append("\n(loop標(biāo)簽1):")
loop@ for (i in 1..5) {
for (j in 1..100) {
if (j == 2) {
tvContent.append(j.toString())
break@loop
}
}
}
// 兩者區(qū)別,這個(gè)是回到第二層的循環(huán)里面
tvContent.append("\n(loop標(biāo)簽2):")
for (i in 1..5) {
loop@ for (j in 1..100) {
if (j == 2) {
tvContent.append(j.toString())
break@loop
}
}
}
標(biāo)簽限制的 break 跳轉(zhuǎn)到剛好位于該標(biāo)簽指定的循環(huán)后面的執(zhí)行點(diǎn)。 continue 繼續(xù)標(biāo)簽指定的循環(huán)的下一次迭代。
標(biāo)簽處返回
Kotlin 有函數(shù)字面量、局部函數(shù)和對(duì)象表達(dá)式。因此 Kotlin 的函數(shù)可以被嵌套。 標(biāo)簽限制的 return 允許我們從外層函數(shù)返回。 最重要的一個(gè)用途就是從 lambda 表達(dá)式中返回。回想一下我們這么寫的時(shí)候:
/**
* 不用標(biāo)簽的方式
*/
fun foo1() {
tvContent.append("\n(講解標(biāo)簽3):");
val ints = arrayOf(0, 1, 2, 3, 4, 5);
ints.forEach {
if (it == 0)
return
tvContent.append(it.toString())
}
}
這個(gè) return 表達(dá)式從最直接包圍它的函數(shù)即 foo 中返回。 (注意,這種非局部的返回只支持傳給內(nèi)聯(lián)函數(shù)的 lambda 表達(dá)式。) 如果我們需要從 lambda 表達(dá)式中返回,我們必須給它加標(biāo)簽并用以限制 return。
/**
* 這個(gè)lit@標(biāo)簽只是返回forEach內(nèi)部,并不是完全斷絕了forEach
*/
fun foo2() {
tvContent.append("\n(講解不同的標(biāo)簽3):");
val ints2 = arrayOf(0, 1, 2, 3, 4, 5);
ints2.forEach lit@{
if (it == 0)
return@lit
tvContent.append(it.toString())
}
}
現(xiàn)在,它只會(huì)從 lambda 表達(dá)式中返回。通常情況下使用隱式標(biāo)簽更方便。 該標(biāo)簽與接受該 lambda 的函數(shù)同名。
/**
* 跟forEach函數(shù)相同則是隱式函數(shù)
*/
fun foo4() {
val ints = arrayOf(0, 1, 2, 3, 4, 5);
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
或者,我們用一個(gè)匿名函數(shù)替代 lambda 表達(dá)式。 匿名函數(shù)內(nèi)部的 return 語句將從該匿名函數(shù)自身返回
/**
* 該匿名函數(shù)能完成跟foo2一樣的效果
*/
fun foo3() {
tvContent.append("\n(講解匿名函數(shù)):");
val ints = arrayOf(0, 1, 2, 3, 4, 5);
ints.forEach(
fun(value: Int) {
if (value == 0) return
tvContent.append(value.toString())
}
)
}