Kotlin控制流

表達(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) ”。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,786評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,986評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,204評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,964評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,354評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,554評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,106評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,918評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,093評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,342評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,755評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,009評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,839評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,107評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容

  • 86.復(fù)合 Cases 共享相同代碼塊的多個(gè)switch 分支 分支可以合并, 寫(xiě)在分支后用逗號(hào)分開(kāi)。如果任何模式...
    無(wú)灃閱讀 1,405評(píng)論 1 5
  • 原文地址 If Expression(if表達(dá)式) 在Kotlin,if是一個(gè)表達(dá)式,也就是它返回一個(gè)值.因此這里...
    CyrusChan閱讀 485評(píng)論 0 1
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,803評(píng)論 18 139
  • 本章將會(huì)介紹 控制流For-In 循環(huán)While 循環(huán)If 條件語(yǔ)句Switch 語(yǔ)句控制轉(zhuǎn)移語(yǔ)句 continu...
    寒橋閱讀 736評(píng)論 0 0
  • 今夜鄜州月,閨中只獨(dú)看。 遙憐小兒女,未解憶長(zhǎng)安。 香霧云鬢濕,清輝玉臂寒。 何時(shí)倚虛幌,雙照淚闌干。
    CHT閱讀 424評(píng)論 0 1