swift控制流

Swift提供了所有C語(yǔ)言中相似的控制流結(jié)構(gòu)。包括for和while循環(huán);if和switch條件語(yǔ)句;break和continue跳轉(zhuǎn)語(yǔ)句等。

Swift還加入了for-in循環(huán)語(yǔ)句,讓編程人員可以在遍歷數(shù)組,字典,范圍,字符串或者其它序列時(shí)更加便捷。

相對(duì)于C語(yǔ)言,Swift中switch語(yǔ)句的case語(yǔ)句后,不會(huì)自動(dòng)跳轉(zhuǎn)到下一個(gè)語(yǔ)句,這樣就避免了C語(yǔ)言中因?yàn)橥沚reak而造成的錯(cuò)誤。另外case語(yǔ)句可以匹配多種類型,包括數(shù)據(jù)范圍,元組,或者特定的類型等。switch語(yǔ)句中已匹配的數(shù)值也可以被用在后續(xù)的case語(yǔ)句體中,where關(guān)鍵詞還能被加入任意的case語(yǔ)句中,來(lái)增加匹配的方式。

1、for循環(huán)

for循環(huán)可以根據(jù)設(shè)置,重復(fù)執(zhí)行一個(gè)代碼塊多次。Swift中提供了兩種for循環(huán)方式:

for-in循環(huán),對(duì)于數(shù)據(jù)范圍,序列,集合等中的每一個(gè)元素,都執(zhí)行一次

for-condition-increment,一直執(zhí)行,知道一個(gè)特定的條件滿足,每一次循環(huán)執(zhí)行,都會(huì)增加一次計(jì)數(shù)

for-in循環(huán)

下面的例子打印出了5的倍數(shù)序列的前5項(xiàng)

    
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

迭代的項(xiàng)目是一個(gè)數(shù)字序列,從1到5的閉區(qū)間,通過使用(…)來(lái)表示序列。index被賦值為1,然后執(zhí)行循環(huán)體中的代碼。在這種情況下,循環(huán)只有一條語(yǔ)句,也就是打印5的index倍數(shù)。在這條語(yǔ)句執(zhí)行完畢后,index的值被更新為序列中的下一個(gè)數(shù)值2,println函數(shù)再次被調(diào)用,一次循環(huán)直到這個(gè)序列的結(jié)尾。

在上面的例子中,index在每一次循環(huán)開始前都已經(jīng)被賦值,因此不需要在每次使用前對(duì)它進(jìn)行定義。每次它都隱式地被定義,就像是使用了let關(guān)鍵詞一樣。注意index是一個(gè)常量。

注意:index只在循環(huán)中存在,在循環(huán)完成之后如果需要繼續(xù)使用,需要重新定義才可以。

如果你不需要序列中的每一個(gè)值,可以使用_來(lái)忽略它,僅僅只是使用循環(huán)體本身:

let base = 3
let power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
println("\(base) to the power of \(power) is \(answer)")
// prints "3 to the power of 10 is 59049"

這個(gè)例子計(jì)算了一個(gè)數(shù)的特定次方(在這個(gè)例子中是3的10次方)。連續(xù)的乘法從1(實(shí)際上是3的0次方)開始,依次累乘以3,由于使用的是半閉區(qū)間,從0開始到9的左閉右開區(qū)間,所以是執(zhí)行10次。在循環(huán)的時(shí)候不需要知道實(shí)際執(zhí)行到第一次了,而是要保證執(zhí)行了正確的次數(shù),因此這里不需要index的值。

同理我們可以使用for-in來(lái)循環(huán)遍歷一個(gè)數(shù)組的元素

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

在遍歷字典的時(shí)候,可以使用key-value對(duì)來(lái)進(jìn)行遍歷。每一個(gè)字典中的元素都是一個(gè)(key, value)元組,當(dāng)遍歷的時(shí)候,可以指定字段的key和value為一個(gè)特定的名稱,這樣在遍歷的時(shí)候就可以更好地理解和使用它們,比如下面例子中的animalName和legCount:

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

字典中的元素在遍歷的時(shí)候一般不需要按照插入的順序,因此不能保證遍歷字典的時(shí)候,元素是有序的。更多跟數(shù)組和字典相關(guān)的內(nèi)容可以參考:Collection Types

另外在數(shù)組和字典中也可以使用類似的遍歷方式,如可以使用for-in循環(huán)來(lái)遍歷字符串中的每一個(gè)字符:

for character in "Hello" {
println(character)
}
// H
// e
// l
// l
// o

For-Condition-Increment條件循環(huán)

Swift同樣支持C語(yǔ)言樣式的for循環(huán),它也包括了一個(gè)條件語(yǔ)句和一個(gè)增量語(yǔ)句:

for var index = 0; index < 3; ++index {
println("index is \(index)")
}
// index is 0
// index is 1
// index is 2

2、while循環(huán)
while循環(huán)執(zhí)行一系列代碼塊,直到某個(gè)條件為false為止。這種循環(huán)最長(zhǎng)用于循環(huán)的次數(shù)不確定的情況。Swift提供了兩種while循環(huán)方式:

while循環(huán),在每次循環(huán)開始前測(cè)試循環(huán)條件是否成立

do-while循環(huán),在每次循環(huán)之后測(cè)試循環(huán)條件是否成立

while循環(huán)

while循環(huán)由一個(gè)條件語(yǔ)句開始,如果條件語(yǔ)句為true,一直執(zhí)行,直到條件語(yǔ)句變?yōu)閒alse。下面是一個(gè)while循環(huán)的一般形式:

var square = 0
var diceRoll = 0
while square < finalSquare {
// roll the dice
if ++diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
if square < board.count {
// if we're still on the board, move up or down for a snake or a ladder
square += board[square]
}
}
println("Game over!")

Do-while循環(huán)

另一種while循環(huán)是do-while循環(huán)。在這種循環(huán)中,循環(huán)體中的語(yǔ)句會(huì)先被執(zhí)行一次,然后才開始檢測(cè)循環(huán)條件是否滿足,下面是do-while循環(huán)的一般形式:


2
3
4
5
6
7
8
9   
do {
// move up or down for a snake or ladder
square += board[square]
// roll the dice
if ++diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
} while square < finalSquare
println("Game over!")

3、條件語(yǔ)句

通常情況下我們都需要根據(jù)不同條件來(lái)執(zhí)行不同語(yǔ)句。比如當(dāng)錯(cuò)誤發(fā)生的時(shí)候,執(zhí)行一些錯(cuò)誤信息的語(yǔ)句,告訴編程人員這個(gè)值是太大了還是太小了等等。這里就需要用到條件語(yǔ)句。

Swift提供了兩種條件分支語(yǔ)句的方式,if語(yǔ)句和switch語(yǔ)句。一般if語(yǔ)句比較常用,但是只能檢測(cè)少量的條件情況。switch語(yǔ)句用于大量的條件可能發(fā)生時(shí)的條件語(yǔ)句。

if語(yǔ)句

在最基本的if語(yǔ)句中,條件語(yǔ)句只有一個(gè),如果條件為true時(shí),執(zhí)行if語(yǔ)句塊中的語(yǔ)句:

var temperatureInFahrenheit = 30
if temperatureInFahrenheit <= 32 {
println("It's very cold. Consider wearing a scarf.")
}
// prints "It's very cold. Consider wearing a scarf."

上面這個(gè)例子檢測(cè)溫度是不是比32華氏度(32華氏度是水的冰點(diǎn),和攝氏度不一樣)低,如果低的話就會(huì)輸出一行語(yǔ)句。如果不低,則不會(huì)輸出。if語(yǔ)句塊是用大括號(hào)包含的部分。

當(dāng)條件語(yǔ)句有多種可能時(shí),就會(huì)用到else語(yǔ)句,當(dāng)if為false時(shí),else語(yǔ)句開始執(zhí)行:

temperatureInFahrenheit = 40
if temperatureInFahrenheit <= 32 {
println("It's very cold. Consider wearing a scarf.")
} else {
println("It's not that cold. Wear a t-shirt.")
}
// prints "It's not that cold. Wear a t-shirt."

在這種情況下,兩個(gè)分支的其中一個(gè)一定會(huì)被執(zhí)行。

同樣也可以有多個(gè)分支,使用多次if和else

temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
println("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
println("It's really warm. Don't forget to wear sunscreen.")
} else {
println("It's not that cold. Wear a t-shirt.")
}
// prints "It's really warm. Don't forget to wear sunscreen."

上面這個(gè)例子中有多個(gè)if出現(xiàn),用來(lái)判斷溫度是太低還是太高,最后一個(gè)else表示的是溫度不高不低的時(shí)候。

當(dāng)然else也可以被省掉

temperatureInFahrenheit = 72
if temperatureInFahrenheit <= 32 {
println("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
println("It's really warm. Don't forget to wear sunscreen.")
}

switch語(yǔ)句

switch語(yǔ)句考察一個(gè)值的多種可能性,將它與多個(gè)case相比較,從而決定執(zhí)行哪一個(gè)分支的代碼。switch語(yǔ)句和if語(yǔ)句不同的是,它還可以提供多種情況同時(shí)匹配時(shí),執(zhí)行多個(gè)語(yǔ)句塊。
每個(gè)switch語(yǔ)句包含有多個(gè)case語(yǔ)句塊,除了直接比較值以外,Swift還提供了多種更加復(fù)雜的模式匹配的方式來(lái)選擇語(yǔ)句執(zhí)行的分支,這在后續(xù)的小節(jié)會(huì)繼續(xù)介紹。

在switch中,每一個(gè)case分支都會(huì)被匹配和檢測(cè)到,所有case沒有提到的情況都必須使用default關(guān)鍵詞。注意default關(guān)鍵詞必須在所有case的最后。

下面的例子用switch語(yǔ)句來(lái)判斷一個(gè)字符的類型:
switch語(yǔ)句的一般結(jié)構(gòu)是:

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")
}
// prints "e is a vowel"

在這個(gè)例子中,首先看這個(gè)字符是不是元音字母,再檢測(cè)是不是輔音字母。其它的情況都用default來(lái)匹配即可。

不會(huì)一直執(zhí)行

跟C和Objective-C不同,Swift中的switch語(yǔ)句不會(huì)因?yàn)樵赾ase語(yǔ)句的結(jié)尾沒有break就跳轉(zhuǎn)到下一個(gè)case語(yǔ)句執(zhí)行。switch語(yǔ)句只會(huì)執(zhí)行匹配上的case里的語(yǔ)句,然后就會(huì)直接停止。這樣可以讓switch語(yǔ)句更加安全,因?yàn)楹芏鄷r(shí)候編程人員都會(huì)忘記寫break。

每一個(gè)case中都需要有可以執(zhí)行的語(yǔ)句,下面的例子就是不正確的:

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a":
case "A":
println("The letter A")
default:
println("Not the letter A")
}
// this will report a compile-time error

元組

case中還可以直接測(cè)試元組是否符合相應(yīng)的條件,_可以匹配任意值。

下面的例子是判斷(x,y)是否在矩形中,元組類型是(Int,Int)

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")
}
// prints "(1, 1) is inside the box"

數(shù)值綁定

在case匹配的同時(shí),可以將switch語(yǔ)句中的值綁定給一個(gè)特定的常量或者變量,以便在case的語(yǔ)句中使用。比如:

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))")
}
// prints "on the x-axis with an x value of 2"

Where關(guān)鍵詞

switch語(yǔ)句可以使用where關(guān)鍵詞來(lái)增加判斷的條件,在下面的例子中:

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")
}
// prints "(1, -1) is on the line x == -y"

4、控制跳轉(zhuǎn)語(yǔ)句

在Swift中控制跳轉(zhuǎn)語(yǔ)句有4種,讓編程人員更好地控制代碼的流轉(zhuǎn),包括:

continue

break

fallthrough

return

其中continue,break和fallthrough在下面詳細(xì)介紹,return語(yǔ)句將在函數(shù)一章介紹。

continue

continue語(yǔ)句告訴一個(gè)循環(huán)停止現(xiàn)在在執(zhí)行的語(yǔ)句,開始下一次循環(huán)。

注意:在for-condition-increment循環(huán)中,increment增量語(yǔ)句依然執(zhí)行,只是略過了一次循環(huán)體。

下面的例子實(shí)現(xiàn)的是去除一個(gè)字符串中的空格和元音字母,從而組成一個(gè)字謎:

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput {
switch character {
case "a", "e", "i", "o", "u", " ":
continue
default:
puzzleOutput += character
}
}
println(puzzleOutput)
// prints "grtmndsthnklk"

遍歷字符串的每一個(gè)字符,當(dāng)遇到元音字母或者空格時(shí)就忽略,進(jìn)行下一次循環(huán),從而得到了最終的字謎。

break

break語(yǔ)句將終止整個(gè)循環(huán)的執(zhí)行,可以用在循環(huán)語(yǔ)句中,也可以用在switch語(yǔ)句中。

let numberSymbol: Character = "三"  // Simplified Chinese for the number 3
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "?", "一", "?":
possibleIntegerValue = 1
case "2", "?", "二", "?":
possibleIntegerValue = 2
case "3", "?", "三", "?":
possibleIntegerValue = 3
case "4", "?", "四", "?":
possibleIntegerValue = 4
default:
break
}
if let integerValue = possibleIntegerValue {
println("The integer value of \(numberSymbol) is \(integerValue).")
} else {
println("An integer value could not be found for \(numberSymbol).")
}
// prints "The integer value of 三 is 3."

上面的例子首先檢查numberSymbol是不是一個(gè)數(shù)字,阿拉伯?dāng)?shù)字,漢字,拉丁文或者泰文都可以。如果匹配完成,則將possibleIntegerValue賦值。最后在通過if語(yǔ)句檢測(cè)是否已被賦值,并綁定到integerValue常量上,最后輸出。default語(yǔ)句用來(lái)迎接未能被上述case匹配的情況,但是不需要做任何事情,因此直接使用break終止即可。

fallthrough

由于Swift中的switch語(yǔ)句不會(huì)自動(dòng)的因?yàn)闆]有break而跳轉(zhuǎn)到下一個(gè)case,因此如果需要想C語(yǔ)言中那樣,依次執(zhí)行每個(gè)case的時(shí)候,就需要用到fallthrough關(guān)鍵詞。

像下面這個(gè)例子一樣,default分支最終都會(huì)被執(zhí)行:

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)
// prints "The number 5 is a prime number, and also an integer."
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Swift 提供了類似 C 語(yǔ)言的流程控制結(jié)構(gòu),包括可以多次執(zhí)行任務(wù)的for和while循環(huán),基于特定條件選擇執(zhí)行...
    窮人家的孩紙閱讀 784評(píng)論 1 1
  • [The Swift Programming Language 中文版]本頁(yè)包含內(nèi)容: Swift提供了多種流程控...
    風(fēng)林山火閱讀 692評(píng)論 0 0
  • Swift提供了多種控制流聲明。包括while循環(huán)來(lái)多次執(zhí)行一個(gè)任務(wù);if,guard和switch聲明來(lái)根據(jù)確定...
    BoomLee閱讀 2,078評(píng)論 0 3
  • 本章將會(huì)介紹 控制流For-In 循環(huán)While 循環(huán)If 條件語(yǔ)句Switch 語(yǔ)句控制轉(zhuǎn)移語(yǔ)句 continu...
    寒橋閱讀 825評(píng)論 0 0
  • 凡事都往好處想 劉墉 我是達(dá)薇, 我的三個(gè)標(biāo)簽是: 1.我是一個(gè)時(shí)間管理的踐行者.也是時(shí)間管理的合伙人。 2我...
    達(dá)薇知心姐姐閱讀 276評(píng)論 0 0

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