Swift5-外行零基礎(chǔ)入門_9-控制流

控制流

什么是控制流?

所謂控制流,是用來控制一件事物的流程的。跟數(shù)據(jù)類型一樣,同樣是模擬我們大腦對現(xiàn)實生活的處理模式。
還記得我在開始舉的例子的嗎?一起來回顧一下:

早晨起(床),吃完(早餐),出門穿上(外套),花(兩元錢)買了公交(車票),到公司開始(干活)。

我們的大腦能夠輕松處理不同的數(shù)據(jù)類型,并且,我們實際上還在處理流程控制。讓我們將上面這個例子細(xì)分一下:

  • 當(dāng)我吃早飯時,只要沒吃完,我就會一直吃,直到吃完或者吃飽;
  • 出門的時候檢查有沒有穿外套,穿了外套再出門;
  • 等公交車時,一輛接一輛,到了我要等的22路公交車,我就上車。
  • 如果我趕上了公交車,我就會到公司干活;

看吧,這里隱藏了相當(dāng)多的條件或循環(huán)。只有通過這種流程控制,我們才能自由處理各個對象。我們的大腦相當(dāng)強大,強大到你根本不需要費勁思考,這些事情就順理成章的完成了。
再說回可憐的計算機,它需要你給他交待具體的任務(wù)安排。就像家長給上小學(xué)的孩子輔導(dǎo)作業(yè)一樣,你需要把自己的認(rèn)知也暫時拉低到小學(xué)水平,這樣你才能給孩子講明白題目。

有哪些控制流?

明白了什么是控制流,我們再來看看,Swift能接受哪些具體的命令來組織事務(wù)的控制流程:

  • for-in 循環(huán):多用在數(shù)據(jù)組合中,對單個數(shù)據(jù)進行逐項遍歷;
  • While 循環(huán):如果某個條件滿足,就一直循環(huán),直到條件不滿足;
  • if 條件語句:如果某個條件滿足,就做某件事,否則就做另一件事;
  • Switch 匹配語句:列舉很多條件,滿足其中某個條件時,做某件事。
    上面,只是簡略的闡述了每個語句的意思,實際運用時,有很多細(xì)節(jié)需要注意,我們逐條來看一下。

1. for-in 循環(huán)

for-in循環(huán)有點像是做上樓梯(每個臺階踩一遍),點名(每個人都要點一遍)這種比較機械的工作。

  • 基本用法
    for-in循環(huán)我們之前已經(jīng)多次用過了,在遍歷數(shù)組,集合,字典中的值時,經(jīng)常用到。
var arrayNumbers = [1,2,3]
for i in arrayNumbers {
    print(i)
}
// 1,2,3
  • 遍歷區(qū)間
    我們之前提到過區(qū)間,比如1...6,就是1,2,3,4,5,6這幾個數(shù)字,也是可以用for in進行遍歷的。
for i in 1...6 {
    print(i)
}
// 1,2,3,4,5,6

在這個例子中,i是1-6范圍的值,每一步都取了一次當(dāng)前值,并打印出來。
我們還可以僅僅執(zhí)行這段循環(huán),而不打印出i。

for i in 1...6 {
    print("Hello")
}
// 打印了六遍"Hello"

在這個例子中,我們并沒有在后面使用i,因此,我們可以用_代替i。

for _ in 1...6 {
    print("Hello")
}
// 同樣打印了六遍"Hello"
  • 步進遍歷
    上樓梯的時候,我可以兩步兩步上;也可以從二樓開始上(也許是坐電梯到的二樓?)。總之,有選擇的可能。
    這時,我們可以使用stride(from:to:by:)或者是stride(from:through:by:),先看下面的例子:
for i in stride(from:2, to: 100, by: 5) {
    print(i)
}
// 請自己在Playground中試一下結(jié)果。

這段代碼實現(xiàn)了更加多的參數(shù),在100這個范圍內(nèi),從2開始數(shù),每隔5數(shù)一次。

2. While 循環(huán)

while condition {
    statements
}

如果說for in做的工作比較機械的話,while,if,switch就比較有目的性了,我們先看while。

  • 基本用法
    首先看一個示例,我會持續(xù)吃,直到我感覺有差不多八成飽。這段描述可以用代碼來表達:
var 飽腹感 = 1
while 飽腹感 < 8 {
    print("再吃一口……")
    飽腹感 += 1
}

分析這段代碼:
首先,我很餓,用變量表示var 飽腹感 = 1,我給自己設(shè)定的條件是要吃到八成飽,飽腹感 < 8這實際上是一個判斷,得出的就是一個判斷值,也就是布爾值,是true or false。
開始飽腹感是1,滿足了飽腹感 < 8這個判斷,就會執(zhí)行while包起來的語句,我會再吃一口,飽腹感就會加1。這時,代碼運行完了,再從頭運行,再次判斷飽腹感的值,直到飽腹感=8的時候,條件就不滿足了,就停止執(zhí)行。
代碼停止了,但是代碼運行了7次再吃一口,也達到了目的。

  • 類比:
    for-in也能實現(xiàn)類似的多次執(zhí)行的效果,但是while更接近自然語言,可以類比中文當(dāng)……時,就……。在合適的情況下使用,代碼的可讀性就會更好。
    這有點像上學(xué)的時候,老師給我們批改作文,會說你這里用詞不當(dāng)。怎么才能用詞恰當(dāng)呢?就需要多讀,多寫,慢慢進步。等到你成年后,你就不太會說:我已經(jīng)飽的無與倫比了,這樣用詞不當(dāng)?shù)脑捔恕?/p>

  • repeat-while

repeat {
    statements
} while condition

理解了while的基本用法后,這里就很好理解。repeat-whilewhile的最大區(qū)別就是,無論什么條件,先執(zhí)行一段代碼。用我們的例子說明,就是管他餓不餓,先吃一口。上面的代碼可以改為:

var 飽腹感 = 8
repeat {
    print("再吃一口……")
    飽腹感 += 1
}
while 飽腹感 < 8

這里,我把飽腹感的初始值設(shè)為8,雖然達到我的八成飽要求了,可是還要首先吃一口再說。

3. if 條件語句

if條件語句的意思是如果……就……,如果某個條件滿足,就執(zhí)行某個動作。一個蘿卜一個坑,對預(yù)期控制的比較精確,也是編程語言中最常用的邏輯控制語句。

  • 基本用法
if condition {
    statements
}

condition同樣是一個布爾值,statements是某個動作。
舉個與生活相關(guān)的例子,如果天氣晴朗,我就出門,用代碼可以表示:

var 天氣 = "晴朗"
if 天氣 == "晴朗" {
    print("我要出門")
}

聲明一下,為了便于理解,我們使用了中文名稱作為變量,swift也能正常執(zhí)行,但是在正式開發(fā)中,盡量避免這樣使用。我能想到的最大缺點就是,這樣做會影響兼容性,因為其他大部分人都不這么干。
上面這段代碼,if的條件是成立的,因此會執(zhí)行print()語句,如果你把天氣的值改為其他,print()就不會執(zhí)行了。

  • if else
    既然是假設(shè),那么我們還會有更復(fù)雜的情況,比如,如果天氣晴朗,我就出門。如果陰天、下雨、大風(fēng)等壞天氣,我就在家上網(wǎng)。這段描述,可以用代碼表示如下:
var 天氣 = "下雨"
if 天氣 == "晴朗" {
    print("我要出門")
} else {
    print("在家上網(wǎng)")
}

這里,加了else的意思是,除了天氣 == "晴朗"這個條件,其他任何情況下,執(zhí)行的動作。
滿足一個條件,執(zhí)行一個命令。如果不滿足這個條件,就執(zhí)行另一個命令。

  • if else if else
    如果有多項判斷,可以使用else if。在上面的例子中,我們可以細(xì)化對不同情況的反應(yīng)。比如,如果天氣晴朗,我就出門;如果下雨,我就帶傘出門;否則,我就在家上網(wǎng)。
var 天氣 = "下雨"
if 天氣 == "晴朗" {
    print("我要出門")
} else if 天氣 == "下雨" {
    print("帶傘出門")
} else {
    print("在家上網(wǎng)")
}

還有一種跟if條件很類似的 guard語句,主要在函數(shù)中使用,我們后面再說。

4. Switch 匹配語句

  • 基本用法
    如果有多項條件,每個條件都各自對應(yīng)一種動作時,除了用多個else if之外,還可以使用switch語句。
var 天氣 = "晴朗"
switch 天氣 {
case "晴朗":
    print("出門遛彎。")
case "下雨":
    print("出門帶傘。")
default:
    print("在家上網(wǎng)。")
}

有沒有發(fā)現(xiàn)switchif的最大區(qū)別?if后面的條件是布爾值,而switch后面是具體的數(shù)據(jù),case后面的值也是從具體的數(shù)據(jù)中做選擇。這樣就靈活了很多。
但是要注意,case是順序執(zhí)行,一旦滿足,后面就不再執(zhí)行了。

  • 復(fù)合匹配
    因此,我們可以輕松使用復(fù)合數(shù)據(jù)進行匹配
var 天氣 = "陰天"
switch 天氣 {
case "晴朗", "陰天":
    print("出門遛彎。")
case "下雨":
    print("出門帶傘。")
default:
    print("在家上網(wǎng)。")
}

我在第一行case中同時列舉了兩個條件,陰天也能出門遛彎。如果是用if,你需要這樣列舉天氣=="晴朗" || 天氣=="陰天",因為if后面只能跟布爾值。

  • 區(qū)間匹配
    非布爾值帶來的好處,還可以使用區(qū)間。舉個另外的我們經(jīng)常用的評分例子:
var 分?jǐn)?shù) = 86
switch 分?jǐn)?shù) {
case 0...60:
    print("不及格")
case 61...80:
    print("良好")
case 81...100:
    print("優(yōu)秀")
default:
    print("分?jǐn)?shù)有誤")
}
  • 元組匹配
    switch還能按元組匹配,也很使用,看下面這個例子:
var 生命 = 90
var 魔法 = 86

switch (生命, 魔法) {
case (100, 100):
    print("英雄的狀態(tài)完美!")
case (_, 30...100):
    print("可以釋放魔法!")
case (0..<30, _):
    print("生命值低,危險!")
default:
    print("分?jǐn)?shù)有誤")
}

從這個例子,可以看到元組匹配的特性:能按元組精確匹配,使用_可以忽略某項匹配,可以按區(qū)間匹配。

  • 值綁定
    我們可以在case分支中,用常量或變量綁定條件中的值,這樣,方便在該分支中,繼續(xù)操作數(shù)據(jù)。
var status = (30,60)
switch status {
case let (生命, 魔法):
    print("生命值:\(生命), 魔法值:\(魔法)")
    let 狀態(tài)值 = 生命 + 魔法
    print("\(狀態(tài)值)")
}

還可以配合where, 進行條件判斷。會讓綁定值顯得更有意義。

var status = (30,60)
switch status {
case let (生命, 魔法) where 生命 + 魔法 > 100:
    print("可以釋放魔法!")
case let (生命, 魔法):
    print("生命值:\(生命), 魔法值:\(魔法)")
    let 狀態(tài)值 = 生命 + 魔法
    print("狀態(tài)值(\(狀態(tài)值))不夠,不能釋放魔法。")

}

調(diào)整狀態(tài)值,能得到不同case執(zhí)行動作,你可以在Playground中多試試。

7. 控制轉(zhuǎn)移語句

最后,我們來簡單介紹幾條控制語句.
continue,break,fallthrough,return,throw
return多用在函數(shù)中,throw多用在錯誤處理中,我們也放在后面介紹。
continue,break,fallthrough這幾個語句主要用在前面所說的各種循環(huán)語句中,因為有時候這些循環(huán)的默認(rèn)執(zhí)行狀態(tài)并不能滿足需求,這時候,可以搭配這些語句,來控制流程的走向。
下面只是舉了部分例子,先想象結(jié)果如何,然后在Playground中驗證試試,也可以按自己的想法修改、調(diào)試:

  • continue
var 天氣 = ["晴朗","雷暴","陰天","下雨"]
for i in 天氣 {
    if i == "雷暴" {
        continue
    } else {
        print("\(i)可以出門")
    }
}

在遍歷循環(huán)的時候,如果遇到“雷暴”,用continue跳過,不做任何事情。

  • break
var 天氣 = ["晴朗","陰天","下雨","雷暴","臺風(fēng)"]
for i in 天氣 {
    if i == "雷暴" {
        break
    } else {
        print("\(i)可以出門")
    }
}

在遍歷的過程中,遇到“雷暴”,整條循環(huán)就停止了,后面就不會繼續(xù)判斷了。

  • fallthrough
var 天氣 = ["晴朗","陰天","下雨","雷暴","臺風(fēng)"]
for i in 天氣 {
    switch i {
    case "晴朗":
        print("可以出門")
    case "陰天":
//        print("可以出門")
        fallthrough
    case "下雨":
        print("帶傘出門")
    default:
        print("在家上網(wǎng)!")
    }
}

在本段代碼中,fallthrough使本段代碼直接交給下一條case處理。使得“陰天”這條case也會打印“帶傘出門?!?/p>

小結(jié)與預(yù)告

掌握了流程控制,我們就可以對數(shù)據(jù)進行操控了。編程的本質(zhì),無非是一系列的假設(shè),判斷,循環(huán)等等。
我們可以利用已經(jīng)學(xué)到的知識,寫很多東西了。比如,

  • 根據(jù)圓的半徑,求圓面積;
  • 已知一個班10個同學(xué)的成績,根據(jù)他們的分?jǐn)?shù)進行不及格,良,優(yōu)的評級;
  • 已知一位英雄的生命值和魔法值,每釋放一次魔法,就消耗10點生命和60點魔法,直到某一個值不能滿足最低的安全值。
    這是三個例子,證明你根據(jù)已有知識,是能夠?qū)懗鲞@樣的程序的,哪怕簡單一些。
    這也是三個作業(yè),沒有標(biāo)準(zhǔn)答案,你試著獨立寫一寫,對我們學(xué)習(xí)下一節(jié)很有幫助。

來點小提示:

  1. 算術(shù)運算符處理數(shù)字
  2. if或switch判斷分?jǐn)?shù)的范圍
  3. 用while循環(huán)包住一個if判斷,在其中進行變量的增減操作
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容