控制流

For循環(huán)

for循環(huán)用來(lái)按照指定的次數(shù)多次執(zhí)行一系列語(yǔ)句貌夕。Swift 提供兩種for循環(huán)形式:

  • for-in用來(lái)遍歷一個(gè)區(qū)間(range),序列(sequence)藏畅,集合(collection)蝙砌,系列(progression)里面所有的元素執(zhí)行一系列語(yǔ)句随夸。
    1.區(qū)間
    <pre><code>for index in 1...5 {
    println("(index) times 5 is (index * 5)")
    }
    // 1 times 5 is 5
    // 2 times 5 is 10
    // 3 times 5 is 15
    // 4 times 5 is 20
    // 5 times 5 is 25
    </code></pre>

2.區(qū)間(忽略對(duì)值的訪問(wèn))
<pre><code>let base = 3
let power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
println("(base) to the power of (power) is (answer)")
// 輸出 "3 to the power of 10 is 59049"
</code></pre>

這個(gè)計(jì)算并不需要知道每一次循環(huán)中計(jì)數(shù)器具體的值靖避,只需要執(zhí)行了正確的循環(huán)次數(shù)即可。下劃線符號(hào)_(替代循環(huán)中的變量)能夠忽略具體的值比默,并且不提供循環(huán)遍歷時(shí)對(duì)值的訪問(wèn)幻捏。
3.遍歷數(shù)組

<pre><code>let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
println("Hello, (name)!")
}
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!</code></pre>

4.遍歷字典

<pre><code>
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
println("(animalName)s have (legCount) legs")
}
// spiders have 8 legs
// ants have 6 legs
// cats have 4 legs
</code></pre>

字典元素的遍歷順序和插入順序可能不同,字典的內(nèi)容在內(nèi)部是無(wú)序的命咐,所以遍歷元素時(shí)不能保證順序篡九。

5.遍歷字符

<pre><code>for character in "Hello" {
println(character)
}
// H
// e
// l
// l
// o
</code></pre>

  • for條件遞增(for-condition-increment)語(yǔ)句,用來(lái)重復(fù)執(zhí)行一系列語(yǔ)句直到達(dá)成特定條件達(dá)成醋奠,一般通過(guò)在每次循環(huán)完成后增加計(jì)數(shù)器的值來(lái)實(shí)現(xiàn)榛臼。
    1.for initialization; condition; increment { statements }
    <pre><code>for var index = 0; index < 3; ++index {
    println("index is (index)")
    }
    // index is 0
    // index is 1
    // index is 2
    </code></pre>

Switch

switch語(yǔ)句會(huì)嘗試把某個(gè)值與若干個(gè)模式(pattern)進(jìn)行匹配伊佃。根據(jù)第一個(gè)匹配成功的模式,switch語(yǔ)句會(huì)執(zhí)行對(duì)應(yīng)的代碼沛善。當(dāng)有可能的情況較多時(shí)航揉,通常用switch語(yǔ)句替換if語(yǔ)句。

  • 正常switch
    <pre><code>let someCharacter: Character = "e"
    switch someCharacter {
    case "a", "e", "i", "o", "u":
    println("(someCharacter) is a vowel")
    case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
    "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
    println("(someCharacter) is a consonant")
    default:
    println("(someCharacter) is not a vowel or a consonant")
    }
    // 輸出 "e is a vowel"
    </code></pre>一個(gè) case 也可以包含多個(gè)模式金刁,用逗號(hào)把它們分開(kāi)(如果太長(zhǎng)了也可以分行寫(xiě))
    <pre><code>switch some value to consider { case value 1, value 2: statements }</code></pre>

不存在隱式的貫穿(No Implicit Fallthrough)
在 Swift 中帅涂,當(dāng)匹配的 case 分支中的代碼執(zhí)行完畢后,程序會(huì)終止switch語(yǔ)句尤蛮,而不會(huì)繼續(xù)執(zhí)行下一個(gè) case 分支媳友。不需要在 case 分支中顯式地使用break語(yǔ)句

  • 區(qū)間匹配(Range Matching)
    case 分支的模式也可以是一個(gè)值的區(qū)間。下面的例子展示了如何使用區(qū)間匹配來(lái)輸出任意數(shù)字對(duì)應(yīng)的自然語(yǔ)言格式:
    <pre><code>
    let count = 3_000_000_000_000
    let countedThings = "stars in the Milky Way"
    var naturalCount: String
    switch count {
    case 0:
    naturalCount = "no"
    case 1...3:
    naturalCount = "a few"
    case 4...9:
    naturalCount = "several"
    case 10...99:
    naturalCount = "tens of"
    case 100...999:
    naturalCount = "hundreds of"
    case 1000...999_999:
    naturalCount = "thousands of"
    default:
    naturalCount = "millions and millions of"
    }
    println("There are (naturalCount) (countedThings).")
    // 輸出 "There are millions and millions of stars in the Milky Way."</code></pre>

  • 匹配元組(Tuple)
    你可以使用元組在同一個(gè)switch語(yǔ)句中測(cè)試多個(gè)值产捞。元組中的元素可以是值醇锚,也可以是區(qū)間。另外坯临,使用下劃線()來(lái)匹配所有可能的值焊唬。
    <pre><code>let somePoint = (1, 1)
    switch somePoint {
    case (0, 0):
    println("(0, 0) is at the origin")
    case (
    , 0):
    println("((somePoint.0), 0) is on the x-axis")
    case (0, _):
    println("(0, (somePoint.1)) is on the y-axis")
    case (-2...2, -2...2):
    println("((somePoint.0), (somePoint.1)) is inside the box")
    default:
    println("((somePoint.0), (somePoint.1)) is outside of the box")
    }
    // 輸出 "(1, 1) is inside the box"</code></pre>

  • 值綁定(Value Bindings)
    case 分支的模式允許將匹配的值綁定到一個(gè)臨時(shí)的常量或變量,這些常量或變量在該 case 分支里就可以被引用了——這種行為被稱為值綁定(value binding)尿扯。

<pre><code>let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
println("on the x-axis with an x value of (x)")
case (0, let y):
println("on the y-axis with a y value of (y)")
case let (x, y):
println("somewhere else at ((x), (y))")
}
// 輸出 "on the x-axis with an x value of 2"</code></pre>

  • Where語(yǔ)句
    case 分支的模式可以使用where語(yǔ)句來(lái)判斷額外的條件求晶。
    <pre><code>let yetAnotherPoint = (1, -1)
    switch yetAnotherPoint {
    case let (x, y) where x == y:
    println("((x), (y)) is on the line x == y")
    case let (x, y) where x == -y:
    println("((x), (y)) is on the line x == -y")
    case let (x, y):
    println("((x), (y)) is just some arbitrary point")
    }
    // 輸出 "(1, -1) is on the line x == -y"</code></pre>

控制轉(zhuǎn)移語(yǔ)句(Control Transfer Statements)

控制轉(zhuǎn)移語(yǔ)句改變你代碼的執(zhí)行順序,通過(guò)它你可以實(shí)現(xiàn)代碼的跳轉(zhuǎn)衷笋。Swift有四種控制轉(zhuǎn)移語(yǔ)句芳杏。

  • continue

continue語(yǔ)句告訴一個(gè)循環(huán)體立刻停止本次循環(huán)迭代,重新開(kāi)始下次循環(huán)迭代辟宗。就好像在說(shuō)“本次循環(huán)迭代我已經(jīng)執(zhí)行完了”爵赵,但是并不會(huì)離開(kāi)整個(gè)循環(huán)體。

注意:

在一個(gè)for條件遞增(for-condition-increment)循環(huán)體中泊脐,在調(diào)用continue語(yǔ)句后空幻,迭代增量仍然會(huì)被計(jì)算求值。循環(huán)體繼續(xù)像往常一樣工作容客,僅僅只是循環(huán)體中的執(zhí)行代碼會(huì)被跳過(guò)秕铛。
<pre><code>let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput {
switch character {
case "a", "e", "i", "o", "u", " ":
continue
default:
puzzleOutput.append(character)
}
}
println(puzzleOutput)
// 輸出 "grtmndsthnklk"</code></pre>

在上面的代碼中,只要匹配到元音字母或者空格字符缩挑,就調(diào)用continue語(yǔ)句但两,使本次循環(huán)迭代結(jié)束,從新開(kāi)始下次循環(huán)迭代供置。這種行為使switch匹配到元音字母和空格字符時(shí)不做處理谨湘,而不是讓每一個(gè)匹配到的字符都被打印。

  • break

break語(yǔ)句會(huì)立刻結(jié)束整個(gè)控制流的執(zhí)行。當(dāng)你想要更早的結(jié)束一個(gè)switch代碼塊或者一個(gè)循環(huán)體時(shí)紧阔,你都可以使用break語(yǔ)句坊罢。

1.循環(huán)語(yǔ)句中的 break

當(dāng)在一個(gè)循環(huán)體中使用break時(shí),會(huì)立刻中斷該循環(huán)體的執(zhí)行擅耽,然后跳轉(zhuǎn)到表示循環(huán)體結(jié)束的大括號(hào)(})后的第一行代碼活孩。不會(huì)再有本次循環(huán)迭代的代碼被執(zhí)行,也不會(huì)再有下次的循環(huán)迭代產(chǎn)生秫筏。

2.Switch 語(yǔ)句中的 break

當(dāng)在一個(gè)switch代碼塊中使用break時(shí)诱鞠,會(huì)立即中斷該switch代碼塊的執(zhí)行,并且跳轉(zhuǎn)到表示switch代碼塊結(jié)束的大括號(hào)(})后的第一行代碼

  • fallthrough

Swift 中的switch不會(huì)從上一個(gè) case 分支落入到下一個(gè) case 分支中这敬。相反航夺,只要第一個(gè)匹配到的 case 分支完成了它需要執(zhí)行的語(yǔ)句,整個(gè)switch代碼塊完成了它的執(zhí)行

如果你確實(shí)需要 C 風(fēng)格的貫穿(fallthrough)的特性崔涂,你可以在每個(gè)需要該特性的 case 分支中使用fallthrough關(guān)鍵字
<pre><code>let integerToDescribe = 5
var description = "The number (integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also"
fallthrough
default:
description += " an integer."
}
println(description)
// 輸出 "The number 5 is a prime number, and also an integer."</code></pre>

注意:

fallthrough關(guān)鍵字不會(huì)檢查它下一個(gè)將會(huì)落入執(zhí)行的 case 中的匹配條件阳掐。fallthrough簡(jiǎn)單地使代碼執(zhí)行繼續(xù)連接到下一個(gè)case 中的執(zhí)行代碼,這和 C 語(yǔ)言標(biāo)準(zhǔn)中的switch語(yǔ)句特性是一樣的冷蚂。

  • 帶標(biāo)簽的語(yǔ)句(Labeled Statements)

在 Swift 中缭保,你可以在循環(huán)體和switch代碼塊中嵌套循環(huán)體和switch代碼塊來(lái)創(chuàng)造復(fù)雜的控制流結(jié)構(gòu)。然而蝙茶,循環(huán)體和switch代碼塊兩者都可以使用break語(yǔ)句來(lái)提前結(jié)束整個(gè)方法體艺骂。因此,顯示地指明break語(yǔ)句想要終止的是哪個(gè)循環(huán)體或者switch代碼塊隆夯,會(huì)很有用钳恕。類似地,如果你有許多嵌套的循環(huán)體蹄衷,顯示指明continue語(yǔ)句想要影響哪一個(gè)循環(huán)體也會(huì)非常有用忧额。

為了實(shí)現(xiàn)這個(gè)目的,你可以使用標(biāo)簽來(lái)標(biāo)記一個(gè)循環(huán)體或者switch代碼塊愧口,當(dāng)使用break或者continue時(shí)睦番,帶上這個(gè)標(biāo)簽,可以控制該標(biāo)簽代表對(duì)象的中斷或者執(zhí)行耍属。

產(chǎn)生一個(gè)帶標(biāo)簽的語(yǔ)句是通過(guò)在該語(yǔ)句的關(guān)鍵詞的同一行前面放置一個(gè)標(biāo)簽托嚣,并且該標(biāo)簽后面還需帶著一個(gè)冒號(hào)。下面是一個(gè)while循環(huán)體的語(yǔ)法厚骗,同樣的規(guī)則適用于所有的循環(huán)體和switch代碼塊注益。

<pre><code>label name: while condition { statements }</code></pre>

下面的例子是在一個(gè)帶有標(biāo)簽的while循環(huán)體中調(diào)用breakcontinue語(yǔ)句,該循環(huán)體是前面章節(jié)中蛇和梯子的改編版本溯捆。這次,游戲增加了一條額外的規(guī)則:
為了獲勝,你必須剛好落在第 25 個(gè)方塊中提揍。
如果某次擲骰子使你的移動(dòng)超出第 25 個(gè)方塊啤月,你必須重新擲骰子,直到你擲出的骰子數(shù)剛好使你能落在第 25 個(gè)方塊中劳跃。
<pre><code>
let finalSquare = 25
var board = [Int](count: finalSquare + 1, repeatedValue: 0)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var square = 0
var diceRoll = 0</code></pre>

這個(gè)版本的游戲使用while循環(huán)體和switch方法塊來(lái)實(shí)現(xiàn)游戲的邏輯谎仲。while循環(huán)體有一個(gè)標(biāo)簽名gameLoop,來(lái)表明它是蛇與梯子的主循環(huán)刨仑。

while循環(huán)體的條件判斷語(yǔ)句是while square !=finalSquare郑诺,這表明你必須剛好落在方格25中。

<pre><code>
gameLoop: while square != finalSquare {
if ++diceRoll == 7 { diceRoll = 1 }
switch square + diceRoll {
case finalSquare:
// 到達(dá)最后一個(gè)方塊杉武,游戲結(jié)束
break gameLoop
case let newSquare where newSquare > finalSquare:
// 超出最后一個(gè)方塊辙诞,再擲一次骰子
continue gameLoop
default:
// 本次移動(dòng)有效
square += diceRoll
square += board[square]
}
}
println("Game over!")</code></pre>

每次循環(huán)迭代開(kāi)始時(shí)擲骰子。與之前玩家擲完骰子就立即移動(dòng)不同轻抱,這里使用了switch來(lái)考慮每次移動(dòng)可能產(chǎn)生的結(jié)果飞涂,從而決定玩家本次是否能夠移動(dòng)。

1.如果骰子數(shù)剛好使玩家移動(dòng)到最終的方格里祈搜,游戲結(jié)束较店。break gameLoop語(yǔ)句跳轉(zhuǎn)控制去執(zhí)行while循環(huán)體后的第一行代碼,游戲結(jié)束容燕。
2.如果骰子數(shù)將會(huì)使玩家的移動(dòng)超出最后的方格梁呈,那么這種移動(dòng)是不合法的,玩家需要重新擲骰子蘸秘。continue gameLoop語(yǔ)句結(jié)束本次while循環(huán)的迭代官卡,開(kāi)始下一次循環(huán)迭代。
3.在剩余的所有情況中秘血,骰子數(shù)產(chǎn)生的都是合法的移動(dòng)味抖。玩家向前移動(dòng)骰子數(shù)個(gè)方格,然后游戲邏輯再處理玩家當(dāng)前是否處于蛇頭或者梯子的底部灰粮。本次循環(huán)迭代結(jié)束仔涩,控制跳轉(zhuǎn)到while循環(huán)體的條件判斷語(yǔ)句處,再?zèng)Q定是否能夠繼續(xù)執(zhí)行下次循環(huán)迭代粘舟。

注意:

如果上述的break語(yǔ)句沒(méi)有使用gameLoop標(biāo)簽熔脂,那么它將會(huì)中斷switch代碼塊而不是while循環(huán)體。使用gameLoop標(biāo)簽清晰的表明了break想要中斷的是哪個(gè)代碼塊柑肴。 同時(shí)請(qǐng)注意霞揉,當(dāng)調(diào)用continue gameLoop去跳轉(zhuǎn)到下一次循環(huán)迭代時(shí),這里使用gameLoop標(biāo)簽并不是嚴(yán)格必須的晰骑。因?yàn)樵谶@個(gè)游戲中适秩,只有一個(gè)循環(huán)體,所以continue語(yǔ)句會(huì)影響到哪個(gè)循環(huán)體是沒(méi)有歧義的。然而秽荞,continue語(yǔ)句使用gameLoop標(biāo)簽也是沒(méi)有危害的骤公。這樣做符合標(biāo)簽的使用規(guī)則,同時(shí)參照旁邊的break gameLoop扬跋,能夠使游戲的邏輯更加清晰和易于理解阶捆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钦听,隨后出現(xiàn)的幾起案子洒试,更是在濱河造成了極大的恐慌,老刑警劉巖朴上,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垒棋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡余指,警方通過(guò)查閱死者的電腦和手機(jī)捕犬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)酵镜,“玉大人碉碉,你說(shuō)我怎么就攤上這事』淳拢” “怎么了垢粮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)靠粪。 經(jīng)常有香客問(wèn)我蜡吧,道長(zhǎng),這世上最難降的妖魔是什么占键? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任昔善,我火速辦了婚禮,結(jié)果婚禮上畔乙,老公的妹妹穿的比我還像新娘君仆。我一直安慰自己,他們只是感情好牲距,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布返咱。 她就那樣靜靜地躺著,像睡著了一般牍鞠。 火紅的嫁衣襯著肌膚如雪咖摹。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天难述,我揣著相機(jī)與錄音萤晴,去河邊找鬼吐句。 笑死,一個(gè)胖子當(dāng)著我的面吹牛店读,可吹牛的內(nèi)容都是我干的蕴侧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼两入,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了敲才?” 一聲冷哼從身側(cè)響起裹纳,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎紧武,沒(méi)想到半個(gè)月后剃氧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阻星,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年朋鞍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妥箕。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滥酥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畦幢,到底是詐尸還是另有隱情坎吻,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布宇葱,位于F島的核電站瘦真,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏黍瞧。R本人自食惡果不足惜诸尽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望印颤。 院中可真熱鬧您机,春花似錦、人聲如沸膀哲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)某宪。三九已至仿村,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兴喂,已是汗流浹背蔼囊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工歌径, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朽色。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓诈豌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親云矫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膳沽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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

  • Swift提供了多種控制流聲明。包括while循環(huán)來(lái)多次執(zhí)行一個(gè)任務(wù)让禀;if挑社,guard和switch聲明來(lái)根據(jù)確定...
    BoomLee閱讀 1,950評(píng)論 0 3
  • Swift 提供了類似 C 語(yǔ)言的流程控制結(jié)構(gòu),包括可以多次執(zhí)行任務(wù)的for和while循環(huán)巡揍,基于特定條件選擇執(zhí)行...
    窮人家的孩紙閱讀 703評(píng)論 1 1
  • [The Swift Programming Language 中文版]本頁(yè)包含內(nèi)容: Swift提供了多種流程控...
    風(fēng)林山火閱讀 565評(píng)論 0 0
  • 本章將會(huì)介紹 控制流For-In 循環(huán)While 循環(huán)If 條件語(yǔ)句Switch 語(yǔ)句控制轉(zhuǎn)移語(yǔ)句 continu...
    寒橋閱讀 717評(píng)論 0 0
  • 突然好想你腮敌,恩阱当,就是這么任性。 分開(kāi)了糜工,整整一年了弊添,懷念,想起啤斗,絲毫不曾減弱表箭。也許這就叫愛(ài)過(guò),而你是什么樣的人我們...
    永遠(yuǎn)的候鳥(niǎo)閱讀 145評(píng)論 0 0