一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Swift - Swift流程控制之循環語句和判斷語句詳解

Swift流程控制之循環語句和判斷語句詳解

2020-12-16 15:10Swift教程網 Swift

這篇文章主要介紹了Swift流程控制之循環語句和判斷語句詳解,文中還使用了一個游戲例子來講解循環語句和判斷語句的使用,需要的朋友可以參考下

Swift提供了所有c類語言的控制流結構。包括for和while循環來執行一個任務多次;if和switch語句來執行確定的條件下不同的分支的代碼;break和continue關鍵字能將運行流程轉到你代碼的另一個點上。

除了C語言傳統的for-condition-increment循環,Swift加入了for-in循環,能更加容易的遍歷arrays, dictionaries, ranges, strings等其他序列類型。

Swift的switch語句也比C語言的要強大很多。 Swift中switch語句的case語句不會“掉入”下一個case,避免了c語言忘記寫break語句產生的錯誤。 case可以匹配許多不同的模式,包括范圍匹配,元組匹配或者拋給指定的類型。匹配值在一個case條件下可以綁定到臨時常量或變量,可以在case的代碼塊中使用,復雜匹配條件下可以表示為每一個case的條件

一、For Loops - For循環

for循環用來多次執行一組語句 ,Swift提供了兩種形式:

1.for-in執行范圍,序列,集合或級數等每一項中的一組語句
2.for-condition-increment執行一組語句直到確定的條件出現,通常在每一個循環結束前遞增一個計數

For-In循環

使用for-in來遍歷集合中的項目,比如數組的范圍,排列中的項或者字符串中的字符。

下面的例子打印了表中的5個元素

復制代碼 代碼如下:

 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


例子中被迭代集合的項是一個封閉范圍內從1到5的數字,就是上面標識為封閉范圍操作符的 (...)。 Index的值被設為第一個數據的范圍(1), 然后執行循環中的語句。在本例中,循環只包含了一句話,根據index現有的值打印5次乘法表的一個結果。當執行完語句之后,index的值被更新為范圍中的第二個值,然后再次調用println函數。這個操作會一直持續,直到范圍的終點。

在上面的例子中,index是一個常量,它的值在每次迭代的開始時自動初始化,使用前不會被聲明,就是簡單的將其隱性聲明納入循環的聲明,不需要使用let來聲明關鍵字。

 

復制代碼 代碼如下:

NOTE:
Index常量僅僅存在于循環的范圍內。如果你想要在循環之后得到index的值,或者想要使用index的值作為變量,你必須在循環之前聲明它。

如果不需要范圍的值,可以用下劃線替代變量名來忽略這些值:

復制代碼 代碼如下:

 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"


例子中計算兩數相乘(在本例中,3乘以10)。乘法初始值為1,每次乘3,乘10次,使用半封閉循環從0到9。這個計算不需要通過循環來知道每個計數器的值--僅僅只需要執行正確的循環次數。下劃線操作符 _ (用于替代循環變量)將忽略掉個體值,并且在每一次循環迭代期間不給現有的變量提供訪問。

使用for-in循環來迭代出array中的每一個項:

復制代碼 代碼如下:

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


同樣可以迭代字典來訪問其中的鍵值對。當迭代字典時里面的每一個項都以(key,value)元組的形式來返回,你可以在for-in的循環體中分解 (key, value) 元組的成員,把成員作為顯性命名的常量來使用。下面例子,字典的key被分解為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


Dictionary中的項的迭代順序可能跟它們插入時的順序不一樣。因為Dictionary中的內容本質上是無序的,所以迭代它們不能保證檢索時的順序。更多關于排列和字典的內容詳見 Collection Types章節。

除了排列和字典,for-in循環還能迭代字符串中的Character(字符):

復制代碼 代碼如下:

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

For-Condition-Increment For-條件-遞增

除了for-in循環,Swift還支持傳統C語言按條件遞增的for循環

復制代碼 代碼如下:

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


這是常用的形式:

復制代碼 代碼如下:

for <initialization>; <condition>; <increment> {
    <statements>
}


封號把循環定義隔為了三個部分,跟C語言一樣。然而與C不同的是,Swift不需要用括號把 “初始化; 條件; 增量” 的代碼塊包起來。

循環按照下面流程執行:

1.當循環第一次進入,initialization expression(初始化表達式)計算一次,設置好循環所需的常量或者變量。

2.計算condition expression(條件表達式)。如果計算結果為false(假),循環終止,并繼續執行for循環尾括號(})后面的代碼。如果結果為(true)真,則執行循環體大括號內的代碼。

3.在所有的語句執行完后,計算increment expression(增量表達式)。計數器可能遞增或遞減,也可能根據語句執行的結果將初始化變量設為新的值。計算完增量表達式返回到第2步,條件表達式再次被計算。

上面描述的循環體的形式和執行過程可以簡單的等同于:

復制代碼 代碼如下:

<initialization>
while <condition> {
    <statements>
    <increment>
}

常量和變量在初始化表達式中的聲明(比如var index = 0)只在for循環自己內部有效。如果需要知道index最終的值,必須在循環開始前聲明index:

復制代碼 代碼如下:

var index: Int
for index = 0; index < 3; ++index {
    println("index is \(index)")
}
// index is 0
// index is 1
// index is 2
println("The loop statements were executed \(index) times")
// prints "The loop statements were executed 3 times"


注意,循環完成后index最終的值是3,不是2。最后一次執行增量表達式調用了++index,把index設為3,使得index<3等于false,循環結束。

二、While Loops - While循環

while循環在條件變為false前執行一組語句,這類循環最好用在第一個迭代開始前并不知道迭代器的數字的時候。Swift提供了兩種while循環:

1.while 在每次通過循環的開頭計算條件
2.do-while 在每次通過循環的結尾計算條件

while循環

一個while循環開始于計算單個的條件,如果條件為true,一組語句將重復直到條件變為false。

這是常見的while形式:

復制代碼 代碼如下:

while <condition> {
    <statements>
}

比如,玩這個叫Snakes and Ladders的游戲(或Chutes and Ladders):

Swift流程控制之循環語句和判斷語句詳解

游戲的規則是這樣的:

1.板子上有25個矩形,然后目標是到達或超越25號方塊。
2.每一輪,你先搖六面骰子,然后按照水平方向的虛線箭頭移動到對應數字的方塊上。
3.如果走完落在梯子的底部,你可以爬上梯子。
4.如果走完落在蛇的頭部,你可以走到那條蛇的尾部。

這個游戲板由一個Int型數組展示出來。它的大小基于finalSquare常量,該常量用來初始化數組并在之后檢查勝利條件。游戲板初始化為26個值為0的Int型數據,不是25個(分別位于0至25的索引):

復制代碼 代碼如下:

let finalSquare = 25
var board = Int


一些方塊給蛇與梯子設有具體的值。游戲板里,你能在有方塊有梯子腳的地方向上移動正數,而有蛇頭的地方你只能向下移動負數:

復制代碼 代碼如下:

board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08


方塊3有梯子腳,所以你可以移動到方塊11。為了表述這個動作,board[03]等于+08,等同于一個整型數值8(即3和11的差)。一元運算符加運算符(+i)與一元減運算符(-i)相平衡,如果數值小于10就用0替代,這樣所板上的定義就對齊了。(風格調整不是必須的,但代碼簡潔很有必要)

玩家開始于方塊0,就在游戲板左下角的外面。第一下投骰是把玩家帶到游戲版里面:

復制代碼 代碼如下:

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!")


這個例子很簡單的模擬了投骰子。用隨機數的生成器來替代,diceRoll從0開始。每一個while循環,diceRoll通過自加運算符(++i)遞增,然后檢查是否過大。++diceRoll的返回值等于diceRoll自加以后的值。如果返回值等于7,骰子值則過大,重設為1。這樣diceRoll的值會一直是1,2,3,4,5,6,1,2等等。

在搖骰子后,玩家根據diceRoll移動方塊。有可能骰子的數會讓玩家超過方塊25,這樣就算游戲結束。為了描述這個場景,代碼在向board[square]添加值以前先檢查square的值是否少于board數組的count屬性,如果是則根據現有的square值將玩家上移或下移到相應梯子或蛇。

如果不執行這個檢查,board[square]會可能嘗試取得board數組界限外的值,導致越界。如果square現在等于26,代碼將嘗試檢查board[26],這個值超過了數組限制。

現有的While循環執行到最后,會檢查循環條件看循環是否會再次執行。如果玩家已經移動或者方塊超過25,循環條件會計算為false,游戲結束。

在這個例子中使用While循環是比較合適的,因為游戲的長度在循環的開頭不明確,讓循環一直執行直到特定的滿足條件出現。

Do-While循環

While循環的另一個形式是do-while,在考慮循環條件前先執行一次整個循環體,然后再繼續重復循環直到條件為false。

下面是do-while的常見形式:

復制代碼 代碼如下:

do {
   <statements>
} while <condition>


再來看看Snakes and Ladders的例子,用do-while而不是while來實現。finalSquare, board, square, 和diceRoll都用相同的方式初始化:

復制代碼 代碼如下:

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


在這個版本的游戲中,循環中第一個操作是檢查一個梯子或蛇。沒有梯子能直接把玩家帶到方塊25,所以不可能只爬一個梯子就贏了。因此在循環里先檢查梯子或蛇會更安全。

游戲的開始,玩家在“方塊0”。 board[0]永遠等于0,沒有別的功能:

復制代碼 代碼如下:

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!")


在代碼檢查后,開始搖骰子,玩家通過diceRoll方塊向前移動,該循一直環執行到最后。

循環條件(while square < finalSquare)跟之前例子一樣,但是這次會在第一次循環的結尾才計算。do-while循環的結構比while循環更適合本例。上面do-while中,在循環條件確認square仍舊在游戲板里面后,square += board[square]會直接進行計算,不必進行數組越界的檢查。

三、Conditional Statements - 條件語句

編程中常常根據不同的條件執行不同的代碼,你可能會要代碼在出錯后運行額外的語句,或者當數值越界時展示一個消息。我們可以用conditional(條件)來實現。

Swift提供兩種方式來添加代碼的分支,常見的if和switch語句。顯然,用if語句來計算只有少量分支的的條件,而Switch用于更復雜的情況,特別是在模式匹配的時候有助于選擇合適的代碼分支來執行。

If語句

在下面最簡單的例子里,if語句有一個if條件。所有的語句都只有在if條件為true的情況下才執行:

復制代碼 代碼如下:

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


前面的例子檢查了溫度是否等于32攝氏度。如果是則打印消息。否則不打印消息,直接執行if語句大括號后面的代碼。

if語句可以提供一個二選一的語句,常見的:else clause,用于當if條件為false時。這些語句用else關鍵字來控制:

復制代碼 代碼如下:

 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."


兩個大括號中的一個被執行。因為溫度增加超過了40攝氏度,已經不需要建議去帶圍巾,所以else分支被觸發。

你可以使用多個if語句,像這樣增加條件:

復制代碼 代碼如下:

 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."


這里增加的if語句用于應對極端炎熱的情況。最后的else條件保留,打印既不冷也不熱的情況。

最后的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.")
 }


在這個例子中,溫度既不冷也不熱才能觸發if或者else條件來打印信息。

Switch語句

Switch語句用一個值來匹配相對應的幾個匹配模式。然后執行相對應的代碼塊,基于一開始匹配成功的模式。switch語句提供了應對多種選擇情況的處理來替代if語句。

最簡單的形式,switch比較一個值對應的一個或者多個相同形式的值:

復制代碼 代碼如下:

 switch some value to consider {
 case value 1:
     respond to value 1
 case value 2,
 value 3:
     respond to value 2 or 3
 default:
     otherwise, do something else
 }


每個switch語句由多個可能的case(情況)構成,都用標記的case關鍵字開頭。除了比較對應的值,Swift還為每種case應對更復雜的匹配模式提供了幾種方法,后面章節再說。

每一個switch語句都必須exhaustive(詳細),并且每一個所考慮類選可能的值都必須匹配switch中的一個case。如果不能對應到switch中的所有case的值,可以定義個默認的選取器來解決。選取器用default關鍵字來表示,必須出現在最后。

下面的例子用switch語句匹配了一個小寫字符,someCharacter:

復制代碼 代碼如下:

 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"


Switch語句第一個case匹配了5個小寫的元音字母。相似地,第二個case匹配所有的輔音小寫字母。

case中并不需要寫上所有其他的英語字母,所以switch提供了default來匹配其他所有不是元音也不是輔音的情況。這樣的條件保證了switch沒有遺漏。

No Implicit Fallthrough - 沒有隱性掉入

相比C和objective-c中的switch語句,Swift中(如果忘了寫break)的switch不會默認的掉落到每個case的下面進入另一個case。相反,switch語句當第一個遇到的case完成時就完成了它整個的執行,不需要寫break。因此比起C語言,swift的switch更加安全和簡單,避免了執行多個case的錯誤。

 NOTE:
 如果你需要,仍舊可在case執行完以前跳出來,詳見:[Break in a Switch Statement]見下面章節
每個case的主干包括只少一個可執行的語句。下面這樣寫是無效的,因為第一個case是空的:

復制代碼 代碼如下:

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


不像C語言中的Switch,這里的switch語句不能匹配"a"和"A"。比如,case "a"會在編譯時報錯:沒有找到任何可執行語句。盡可能的避免了意外從一個case掉入另一個,這樣使代碼更安全。

如果有多個匹配對象的,可以用逗號隔開,像下面這樣寫成多行:

復制代碼 代碼如下:

switch some value to consider {
case value 1,
value 2:
    statements
}

 

復制代碼 代碼如下:

NOTE:
為特別的switch case選擇掉落行為,可以使用fallthrough關鍵字,在下文中詳解

Range Matching - 范圍匹配

switch中case的值可以檢查他們內在的范圍。這個例子使用數字范圍可以提供任意大小數字的自然語言計數。

復制代碼 代碼如下:

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).")
// prints "There are millions and millions of stars in the Milky Way."

Tuples 元組

你可以使用元組在相同的switch語句中測試多個值。每一個元組中的元素都可以試著和范圍中不同的值進行匹配。另外,用下劃線(_)標示符來匹配任意可能的值。

下面例子中使用一個點坐標(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"

Swift流程控制之循環語句和判斷語句詳解

Switch語句決定了點是否在原點(0,0)上,在紅色的x軸上,在橙色的y軸上,在藍色4X4的矩形為中心的原點內,或者在矩形外。

與C語言不同,Swift允許多個switch的case考慮相同的值。實際上點(0,0)能匹配例子中所有的四個case。然而,如果多個匹配出現,第一個匹配成功的case將被使用。點(0,0)能首先匹配case(0,0),所以其他所有的case將被忽略。

Value Bindings 值綁定

一個switch的case能綁定用于匹配臨時常量或變量值,在case的分支代碼里使用。這就是value binding(值綁定),因為這些值在case的代碼體中是臨時常量或變量的“邊界”。

下面的例子有一個點(x,y),用元組型(Int,Int)來表示,在圖種展示出來如下:

復制代碼 代碼如下:

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

Swift流程控制之循環語句和判斷語句詳解

switch語句來確定點是否在紅色x軸上,在橙色y軸,或者其他地方。

三個switch的case都聲明了占位常量x和y,暫時從anotherPoint占用一個或兩個元組值。第一個case里,case (let x, 0),匹配給任意一個y值為0,并分派點的x值給臨時常量x的點。相似地,第二個case,case (0, let y),匹配給一個x值為0,分派點的y值給臨時常量y的點。

一旦臨時常量被聲明,他們將在case的代碼塊中使用。這里他們將作為簡寫在println函數中打印出來。

注意switch語句沒有default的case。最后一個case,case let (x, y),聲明了包含兩個占位常量可以匹配任何值的元組。作為結果,它匹配任何可能的值,不需要default語句switch就足夠完美了。

上面的例子中,聲明x和y用了關鍵詞let,因為這里不需要在case的代碼段里改變它們的值。然而,他們可以用變量來代替,使用var關鍵詞。如果用了變量,則會創建臨時變量并初始化為合適的值。任何對變量的改變都只會影響case代碼段中的部分。

Where語句

switch的case能使用where子句來進一步判斷條件。 下面的例子將點(x,y)在下圖種分類:

復制代碼 代碼如下:

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"

Swift流程控制之循環語句和判斷語句詳解

switch語句判斷了點是否在綠色斜線上且x == y,或在紫色斜線上且x == -y,或都不是。

三個switch的case聲明了占位常量x和y,臨時占用point中元組值。這些常量作為where子句的一部分,用來創建動態的篩選。只有當where子句的條件結果為true,Switch的case則會匹配現有point的值。

就像在前一個例子中,最后的case匹配所有可能的值,所以不需要default。

Control Transfer Statements - 控制轉移語句

控制轉移語句能改變已經執行代碼的順序,能使代碼跳轉到別的部分。Swift有四個句子:

1.continue
2.break
3.fallthrough
4.return

control, break和fallthrough在下文中詳解。reture語句在Functions中描述。

Continue

Continue語句告訴循環體終止現在的操作,然后開始迭代下一個循環。好像在說“我這次迭代做完啦”,總之不會離開循環體。

 

復制代碼 代碼如下:

NOTE:
在for-condition-increment循環中,調用了continue后累加器依舊會計算。循環會繼續像平時一樣工作,只有循環體中的代碼會被跳過。

下面例子中從一個小寫字符串中移除了所有的元音和空格,創建了個字謎短語:

復制代碼 代碼如下:

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"


上面代碼里,只要匹配到元音字母或空格,就會觸發continue關鍵字。使本次迭代立即終止,然后直接跳入下次迭代的開頭。這個方式使得switch代碼塊能匹配(和忽略)元音字母與空格,比用代碼塊把每一個要打印字符都匹配一次的好。

Break

Break語句能立即終止整個控制流。可以根據你想要的在switch或循環語句里的任何地方終止整個執行。

Break in a Loop Statement - 循環中的Break

當在循環體中使用break,循環會立即停止,并將控制流帶到循環體括號(})后方的第一行代碼里。循環體里其他的代碼不會被執行,也不會開始下一次迭代。

Break in a Switch Statement - Switch中的break

在switch里使用break,switch語句會立即終止,并將控制流帶到switch語句括號(})后方的第一行代碼里。

這種特性可以用于switch里匹配(或忽略)一個或多個case。因為Swift的switch是窮舉的,并且不允許有空case的,有時候要慎重的匹配和為了使意圖明顯而忽略了case。當switch匹配了break語句,case中的break能直接終止整個switch。

 

復制代碼 代碼如下:

NOTE:
一個switch的case只能包含一個作為編譯錯誤的注釋。注釋不是語句,不會導致switch的case被忽略。只能使用break語句來跳過case。

下面的例子中switch有一個字符值,并且判斷四種語言之一中是否有數字符號。一個簡單的switch中包含了多個值:

復制代碼 代碼如下:

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判斷是否是拉丁語,阿拉伯語,中文或者泰文符號來得到1至4的數字。如果匹配成功,其中的一個case里會賦給可選型Int變量possibleIntegerValue一個合適的整型值。

在switch語句執行完成后,例子里用了可選型綁定來確定值是否被發現。possibleIntegerValue變量有一個隱性的初始值nil,具有可選型的優點。只有在前四個case中,當possibleIntegerValue被賦了實際的值可選綁定才會成功。

在上面例子中列出所有可能的字符值不太實際,所以default能提供一個沒任何字符被選中情況下的容器。這的default不用執行任何操作,只寫個簡單的break。一旦default被匹配,break語句立即終止switch,并繼續執行 if let語句。

Fallthrough

Swift中的Switch不會掉下到case的下方并進入下一個case。因此,整個switch語句毀在第一個匹配的case完成后結束。相反,C語言要求你在每個case的末尾插入一個break來防止掉入。相比于C語言,Swift的switch禁止默認掉入讓更加簡潔和可控,這樣避免了執行多個case的錯誤。

如果你確實需要C式的掉入特性,你可以使用fallthrough關鍵詞。下面的例子用fallthrough來創建一段描述數字的文本:

復制代碼 代碼如下:

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."


例子中聲明了一個名為description的String型變量并分派一個初始值。然后函數用switch匹配integerToDescribe的值。如果integerToDescribe的值符合素數列表中的一項,最后的description會增加一段字符,注意數字都是素數。然后用fallthrough關鍵字讓代碼“掉到”default里。default的代碼中再額外的給字符串添加些描述,最后switch結束。

如果integerToDescribe不跟素數表中任何一項匹配,那根本就不會匹配switch的第一個case。這里面沒有其他的case,因此integerToDescribe直接進入default容器。

在switch執行完成后,數字的描述用println函數打印出來。在本例中,5是正確的答案。

 

復制代碼 代碼如下:

NOTE:
fallthrough關鍵字不檢查case里的條件,會直接掉入下一個case。fallthrough簡單的讓代碼執行到下一個case(或default)的代碼塊中,和標準C語言的特性一樣。

Labeled Statements - 標簽語句

你可以嵌套循環或在switch語句中嵌套其他的循環,Swift語句種的switch可以創建復雜的控制流結構。 然而,循環和switch語句都可以過早地使用break。因此,有時明確的使用break來終止代碼很有用。類似的,如果你有多個嵌套的循環,continue會更有用。

為了做到這一點,你可以用statement label來標記循環或switch,與break或continue語句一起使用這個標簽來終止或繼續標記語句的執行。

標簽語句作為引導關鍵詞在標簽的同一行,后面跟著冒號“:”。 這里有一個用了該符號的while循環例子,所有的循環和switch都是相同的。

 

復制代碼 代碼如下:

<label name>: while <condition> {
    <statements>
}

下面的例子里有一個用了標簽的while循環,使用了break和continue語句,Snakes and Ladders游戲可以在上文中看到:

為了勝利,你必須恰好到達25號方塊
如果骰子帶你超過了25號方塊,你必須重新丟骰子直到正好抵達25號方塊。

游戲板和上文中的一樣

Swift流程控制之循環語句和判斷語句詳解

變量 finalSquare, board, square, diceRoll的初始化都跟前文一樣:

 

復制代碼 代碼如下:

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

這個版本用while循環和switch語句來實現游戲邏輯。While循環的標簽為gameLoop,為Snakes and Ladders Game標記出游戲主體。

While循環的條件是while square != finalSquare,意思是你必須落在25號方塊上:

 

復制代碼 代碼如下:

gameLoop: while square != finalSquare {
    if ++diceRoll == 7 { diceRoll = 1 }
    switch square + diceRoll {
    case finalSquare:
        // diceRoll will move us to the final square, so the game is over
        break gameLoop
    case let newSquare where newSquare > finalSquare:
        // diceRoll will move us beyond the final square, so roll again
        continue gameLoop
    default:
        // this is a valid move, so find out its effect
        square += diceRoll
        square += board[square]
    }
}
println("Game over!")

骰子在每個循環的最開始搖動。然后玩家立即移動,switch語句用來判斷移動的結果,算出是否允許移動:

如果骰子帶玩家抵達最后的方塊,游戲結束。break gameLoop語句將控制流帶到游戲結束的地方,即while循環外的第一行。
如果骰子超過了最后的方塊,則移動無效,玩家需要再次投骰。break gameLoop會終止本次迭代,開始下次迭代。
在其他的情況下,骰子有效。玩家向前移動方塊并根據游戲邏輯檢查蛇或梯子。循環結束,控制流返回到while條件判斷處,決定是否需要再次迭代。

NOTE 如果上面的break語句不使用gameLoop標簽,將會中斷switch語句,而不是while語句。使用gameLoop標簽可以更加明確的讓控制流終止。

同樣要注意,當調用continue gameLoop來跳到下一個迭代循環中不是必須使用gameLoop標簽。因為這里只有一個循環體,不會受到其他循環體的影響。然而,用了gameLoop標簽也沒什么不好。這樣做保持與break旁邊的標簽統一,有助于讓游戲邏輯能更加清晰閱讀和理解。

延伸 · 閱讀

精彩推薦
  • SwiftSwift教程之基礎數據類型詳解

    Swift教程之基礎數據類型詳解

    這篇文章主要介紹了Swift教程之基礎數據類型詳解,本文詳細講解了Swift中的基本數據類型和基本語法,例如常量和變量、注釋、分號、整數、數值類型轉換等...

    Swift教程網5162020-12-18
  • Swiftswift where與匹配模式的實例詳解

    swift where與匹配模式的實例詳解

    這篇文章主要介紹了swift where與匹配模式的實例詳解的相關資料,這里附有簡單的示例代碼,講的比較清楚,需要的朋友可以參考下...

    追到夢的魔術師14382021-01-06
  • SwiftSwift的74個常用內置函數介紹

    Swift的74個常用內置函數介紹

    這篇文章主要介紹了Swift的74個常用內置函數介紹,這篇文章列舉出了所有的Swift庫函數,內置函數是指無需引入任何模塊即可以直接使用的函數,需要的朋友可...

    Swift教程網5802020-12-19
  • SwiftSwift能代替Objective-C嗎?

    Swift能代替Objective-C嗎?

    這是我在網上上看到的答案,復制粘貼過來和大家分享一下,因為我和很多人一樣很關心Swift的出現對Mac開發的影響和對Objective-C的影響。...

    Swift教程網4412020-12-16
  • SwiftSwift中轉義閉包示例詳解

    Swift中轉義閉包示例詳解

    在Swift 中的閉包類似于結構塊,并可以在任何地方調用,下面這篇文章主要給大家介紹了關于Swift中轉義閉包的相關資料,需要的朋友可以參考下...

    小小小_小朋友11412021-12-26
  • Swiftmac git xcrun error active developer path 錯誤

    mac git xcrun error active developer path 錯誤

    本文主要是講訴了如何解決在mac下使用git;xcode4.6的環境時,出現了錯誤(mac git xcrun error active developer path)的解決辦法,希望對大家有所幫助...

    Swift教程網2232020-12-16
  • SwiftSwift實現多個TableView側滑與切換效果

    Swift實現多個TableView側滑與切換效果

    這篇文章主要為大家詳細介紹了Swift實現多個TableView側滑與切換效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    乞力馬扎羅的雪雪5822021-01-08
  • SwiftSwift使用CollectionView實現廣告欄滑動效果

    Swift使用CollectionView實現廣告欄滑動效果

    這篇文章主要為大家詳細介紹了Swift使用CollectionView實現廣告欄滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Stevin的技術博客12372021-01-13
主站蜘蛛池模板: 久久黄色小视频 | 欧美日韩一区二区中文字幕视频 | 亚洲AV精品一区二区三区不卡 | 男女性潮高片无遮挡禁18 | 无人区在线观看免费国语完整版 | 99久久精品免费看国产一区二区 | 骚b小说| 交欧美| 99久久国产综合精品1尤物 | 成人深夜视频 | 青青网站 | 免费一级特黄特色大片在线 | 五月天色小说 | 五月婷婷丁香在线视频 | 欧美色成人tv在线播放 | 色狠狠成人综合网 | 我的家教老师在线观看 | 国内精品99 | 国模娜娜一区二区三区 | 日韩免费视频播放 | 欧美性4khd720 | 爱情岛论坛亚洲自拍 | 亚洲精品无码不卡 | 无人区大片免费播放器 | 国产精品久久国产精品99盘 | 啪啪国产视频 | 亚洲AV 中文字幕 国产 欧美 | 久久久精品日本一区二区三区 | 午夜AV内射一区二区三区红桃视 | 欧亚尺码专线欧洲s码wmy | 久草青青在线 | 亚洲国产天堂久久精品网 | 九九艹 | 91久久99热青草国产 | 青青草影院在线观看 | 精品一区二区三区色花堂 | 97成网| 国产精品久久毛片完整版 | 成人网子| 国产一区二区不卡视频 | 欧美人畜|