iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Mobile Development

新手向Android&Kotlin學習紀錄30天系列 第 17

第17天 kotlin小學堂(6) 控制流程 : 跳脫字元

  • 分享至 

  • xImage
  •  

從上一篇在迴圈裡都是從頭執行到尾,但是如果執行到一半就以滿足需求或者就是想跳過某一次特定條件的迴圈,該怎麼辦呢?

跳脫字元

  • break : 終止最直接包圍它的循環。
  • continue : 繼續下一次最直接包圍它的循環。
  • return :默認從最直接包圍它的函數或者匿名函數返回。
    有看沒有懂。
    直接放進有內外兩層for loop比較一下,跑一個外層跟內層都是1..3區間的loop,然後(i,j)字串形式印出每次迴圈的結果:

註:有雙層迴圈的話,從外圈進入內迴圈後,內迴圈完整跑完一次,才會在跳到外迴圈進入下一輪循環喔。換句話說,外迴圈的每一次都包含了完整執行完畢的內迴圈。看下面的輸出結果就會理解:

  • 沒有跳脫字元的長這樣
 print("完整跑完(i,j)  : ")
    for (i in 1..3) {
        for (j in 1..3) {
            print("($i,$j) ")
        }
        print("| ")//完成每次內迴圈(j:1,2,3)後,開始下次外迴圈前印出
    }
//完整跑完(i,j)  : (1,1) (1,2) (1,3) | (2,1) (2,2) (2,3) | (3,1) (3,2) (3,3) |

跳脫字元都放在同樣位置(內圈j==2)來比較印出的結果

  • 跳脫字元break : 到break點時就會直接終止內迴圈執行,執行下一次的外迴圈
print("j==2 break   : ")
    for (i in 1..3) {
        for (j in 1..3) {
            if (j == 2) break
            print("($i,$j) ")
        }
        print("| ")
    }
//j==2 break   : (1,1) | (2,1) | (3,1) | 
  • 跳脫字元continue : 會跳過當下的內迴圈,其餘流程正常,將剩下的內迴圈執行完畢,開始下次外迴圈。
 print("j==2 continue: ")
    for (i in 1..3) {
        for (j in 1..3) {
            if (j == 2) continue
            print("($i,$j) ")
        }
        print("| ")
    }
//j==2 continue: (1,1) (1,3) | (2,1) (2,3) | (3,1) (3,3) |
  • 跳脫字元return :直接終止本次內外迴圈的執行。如果是單層迴圈效果是跟break一樣。
 print("j==2 return  : ")
    for (i in 1..3) {
        for (j in 1..3) {
            if (j == 2) return
            print("($i,$j) ")
        }
        print("| ")
    }
// j==2 return  : (1,1)

對人不要貼標籤,對kotlin表達式可以

上一段介紹的是不帶標籤的使用跳脫字元,kotlin還提供了標籤這個方便的東西,看起來蠻玄的,但是使用蠻簡單的

標籤(label)

在Kotlin 中任何表達式都可以用標籤(label)來標記。標籤的格式為標識符後跟@符號,例如:abc@、fooBar@都是有效的標籤。要為一個表達式加標籤,我們只要在其前加標籤即可

(看起來是廢話但是真的是這樣)

  • 帶標籤的break :在外層for loop前加上outer@的標籤,在break後加上@outer(中間不留空),標籤名可以自訂,兩處的標籤名要一致。下例表示一碰到break@outer這個點等於中斷標籤outer@的表達式。
  • 如果是break@inner表示中斷inner@標籤的內層迴圈,就跟沒加標籤時效果相同。
 print("j==2 break@outer : ")
    outer@ for (i in 1..3) {
        inner@ for (j in 1..3) {
            if (j == 2) break@outer //break@outer中間不留空格
            print("($i,$j) ")
        }
        print("| ") //這行執行不到
    }
//j==2 break@outer : (1,1) 

在while loop 中:本例直接break中斷了內外迴圈

 var num = 1
    outer@while (num < 4) {
        var num2 = 1
        while (num2 < 4) {
            if (num2 == 2) break@outer
            print("($num,$num2) ")
            num2 ++
        }
        num ++
    }
// 結果 : (1,1) 
  • 帶標籤的 continue : 內圈一到j==2時結束內圈跳回標邊處繼續,完全執行不到j==3
 print("j==2 continue@outer: ")
    outer@ for (i in 1..3) {
        inner@ for (j in 1..3) {
            if (j == 2) continue@outer
            print("($i,$j) ")
        }
        print("| ")     //這行執行不到
    }
// j==2 continue@outer: (1,1) (2,1) (3,1) 
  • 帶標籤的 return : 使用forEach這個函數來舉例,forEach{}並不是迴圈,但可以對集合或區間的每一個元素來做一些動作。使用forEach的時候,由於不是loop,所以無法使用breakc和continue就只能使用return。
  • 先看看雙層forEach下使用return
//1.單純使用return  
  (1..3).forEach{i->
        (1..3).forEach{ j->
            if (j==2) return
            print("($i,$j) ")  
    //結果 : (1,1) 
        }
    }
 
//2.搭配標籤返回內層
(1..3).forEach outer@ {i->
        (1..3).forEach inner@{ j->
            if (j==2) return@inner
            print("($i,$j) ")
    //結果 : (1,1) (1,3) (2,1) (2,3) (3,1) (3,3) 
        }
    }

//3.搭配標籤返回外層
(1..3).forEach outer@ {i->
        (1..3).forEach inner@{ j->
            if (j==2) return@outer
            print("($i,$j) ")
    //結果 : (1,1) (2,1) (3,1) 
        }
    }
//4.loop中使用label 返回forEach函數
print("j==2 return@outer: ")
    (1..3).forEach outer@ {i->
        inner@ for (j in 1..3)  {
            if (j == 2) return@outer
            print("($i,$j) ")
        }
        print("執行不到 ")
    }
//結果 : j==2 return@outer: (1,1) (2,1) (3,1) 

  • 隱式標籤,即標籤與函數同名,不必特別標示另外的lebal
 val names = listOf("Ann", "Bob", "Carol", "David", "Emily", "Frank")
    print("names : ")
    names.forEach {
        //列印字母長度5的名字,其他就不印略過
        if(it.length == 5) print("$it, ") else return@forEach
    }
//結果 : names : Carol David Emily Frank 

注意

帶或不帶標籤的break和continue都只能在loop中使用,不能在函數中。
而帶標籤的return則是需要返回到一個函數而不是loop,可以在loop中使用return@label返回到label@函數

就是醬,明天見


上一篇
第16天 kotlin小學堂(5) 控制流程 : for loop、while loop
下一篇
第18天 kotlin小學堂(7) : Function 函數
系列文
新手向Android&Kotlin學習紀錄30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言