Swift教程之掌握流詳解。本站提示廣大學習愛好者:(Swift教程之掌握流詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是Swift教程之掌握流詳解正文
Swift供給了一切C說話中類似的掌握流構造。包含for和while輪回;if和switch前提語句;break和continue跳轉語句等。
Swift還參加了for-in輪回語句,讓編程人員可以在遍歷數組,字典,規模,字符串或許其它序列時加倍便捷。
絕對於C說話,Swift中switch語句的case語句後,不會主動跳轉到下一個語句,如許就防止了C說話中由於忘卻break而形成的毛病。別的case語句可以婚配多品種型,包含數據規模,元組,或許特定的類型等。switch語句中已婚配的數值也能夠被用在後續的case語句體中,where症結詞還能被參加隨意率性的case語句中,來增長婚配的方法。
1、for輪回
for輪回可以依據設置,反復履行一個代碼塊屢次。Swift中供給了兩種for輪回方法:
for-in輪回,關於數據規模,序列,聚集等中的每個元素,都履行一次
for-condition-increment,一向履行,曉得一個特定的前提知足,每次輪回履行,都邑增長一次計數
for-in輪回
上面的例子打印出了5的倍數序列的前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,然後履行輪回體中的代碼。在這類情形下,輪回只要一條語句,也就是打印5的index倍數。在這條語句履行終了後,index的值被更新為序列中的下一個數值2,println函數再次被挪用,一次輪回直到這個序列的開頭。
在下面的例子中,index在每次輪回開端前都曾經被賦值,是以不須要在每次應用前對它停止界說。每次它都隱式地被界說,就像是應用了let症結詞一樣。留意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的0次方)開端,順次累乘以3,因為應用的是半閉區間,從0開端到9的左閉右開區間,所所以履行10次。在輪回的時刻不須要曉得現實履行到第一次了,而是要包管履行了准確的次數,是以這裡不須要index的值。
同理我們可使用for-in來輪回遍歷一個數組的元素
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
println("Hello, \(name)!")
}
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!
在遍歷字典的時刻,可使用key-value對來停止遍歷。每個字典中的元素都是一個(key, value)元組,當遍歷的時刻,可以指定字段的key和value為一個特定的稱號,如許在遍歷的時刻便可以更好地輿解和應用它們,好比上面例子中的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
字典中的元素在遍歷的時刻普通不須要依照拔出的次序,是以不克不及包管遍歷字典的時刻,元素是有序的。更多跟數組和字典相干的內容可以參考:Collection Types
別的在數組和字典中也能夠應用相似的遍歷方法,如可使用for-in輪回來遍歷字符串中的每個字符:
for character in "Hello" {
println(character)
}
// H
// e
// l
// l
// o
For-Condition-Increment前提輪回
Swift異樣支撐C說話款式的for輪回,它也包含了一個前提語句和一個增量語句:
for var index = 0; index < 3; ++index {
println("index is \(index)")
}
// index is 0
// index is 1
// index is 2
上面是這類for輪回的普通構造:
for initialization; condition; increment {
statements
}
分號在這裡用來分隔for輪回的三個構造,和C說話一樣,然則不須要用括號來包裹它們。
這類for輪回的履行方法是:
1、當進入輪回的時刻,初始化語句起首被履行,設定好輪回須要的變量或常量
2、測試前提語句,看能否知足持續輪回的前提,只要在前提語句是true的時刻才會持續履行,假如是false則會停滯輪回。
3、在一切的輪回體語句履行終了後,增量語句履行,能夠是對計數器的增長或許是削減,或許是其它的一些語句。然後前往步調2持續履行。
這類輪回方法還可以被描寫為上面的情勢:
initialization
while condition {
statements
increment
}
在初始化語句中被界說(好比var index = 0)的常量和變量,只在for輪回語句規模內有用。假如想要在輪回履行以後持續應用,須要在輪回開端之前就界說好:
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增1以後,前提語句index < 3前往false,輪回才終止,而這時候,index曾經為3了。
2、while輪回
while輪回履行一系列代碼塊,直到某個前提為false為止。這類輪回最長用於輪回的次數不肯定的情形。Swift供給了兩種while輪回方法:
while輪回,在每次輪回開端前測試輪回前提能否成立
do-while輪回,在每次輪回以後測試輪回前提能否成立
while輪回
while輪回由一個前提語句開端,假如前提語句為true,一向履行,直到前提語句變成false。上面是一個while輪回的普通情勢:
while condition {
statements
}
上面的例子是一個簡略的游戲,Snakes and Ladders,蛇和梯子:
游戲的規矩是如許的:
游戲面板上有25個格子,游戲的目的是達到第25個格子;
每一個回合經由過程一個6面的骰子來決議行走的步數,行走的道路按右圖所示;
假如落在梯子的底部,那末就爬上誰人梯子達到別的一個格子;
假如落到蛇的頭部,就會滑到蛇尾部地點的格子。
游戲面板由一個Int數組構成,年夜小由一個常量設置finalSquare,同時用來檢測能否達到了成功的格子。游戲面板由26個Int數字0初始化(不是25個,由於從0到25有26個數字)
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
第三個格子是一個梯子的底部,表現玩家可以經由過程梯子達到第11格,是以設置board[3]為+08,表現進步8步。同理蛇的地位設置為正數,表現撤退退卻i步。
玩家從為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!")
這個例子用到了一個異常簡略的擲骰子的方法,就是每次加1,而不是應用一個隨機數。diceRoll用來表現每次行走的步數,須要留意的是,每次履行前,++diceRoll都邑先履行加1,然後再與7比擬,假如等於7的話,就設置為1,是以可以看出diceRoll的變更是1,2,3,4,5,6,1……
在擲骰子以後,玩家挪動diceRoll指導的步數,這時候能夠曾經跨越了finalSquare,是以須要停止if斷定,假如為true的話,履行該格子上的事宜:假如是通俗格子就不動,假如是梯子或許蛇就挪動響應的步數,這裡只須要直接應用square += board[square]便可以了。
在while輪回履行終了以後,從新檢討前提square < finalSquare能否成立,持續游戲直到游戲停止。
Do-while輪回
另外一種while輪回是do-while輪回。在這類輪回中,輪回體中的語句會先被履行一次,然後才開端檢測輪回前提能否知足,上面是do-while輪回的普通情勢:
do {
statements
} while condition
下面的蛇與梯子的游戲應用do-while輪回來寫可以如許完成。初始化語句和while輪回的相似:
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格,所以游戲不會直接停止,接上去的進程就和下面的while輪回相似了,輪回的前提語句照樣檢測能否曾經到達終究格子。
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、前提語句
平日情形下我們都須要依據分歧前提來履行分歧語句。好比當毛病產生的時刻,履行一些毛病信息的語句,告知編程人員這個值是太年夜了照樣太小了等等。這裡就須要用到前提語句。
Swift供給了兩種前提分支語句的方法,if語句和switch語句。普通if語句比擬經常使用,然則只能檢測大批的前提情形。switch語句用於年夜量的前提能夠產生時的前提語句。
if語句
在最根本的if語句中,前提語句只要一個,假如前提為true時,履行if語句塊中的語句:
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華氏度(32華氏度是水的冰點,和攝氏度紛歧樣)低,假如低的話就會輸入一行語句。假如不低,則不會輸入。if語句塊是用年夜括號包括的部門。
當前提語句有多種能夠時,就會用到else語句,當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."
在這類情形下,兩個分支的個中一個必定會被履行。
異樣也能夠有多個分支,應用屢次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."
下面這個例子中有多個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.")
}
在這個例子中,溫度不高不低的時刻不會輸出任何信息。
switch語句
switch語句考核一個值的多種能夠性,將它與多個case比擬較,從而決議履行哪個分支的代碼。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語句塊,除直接比擬值之外,Swift還供給了多種加倍龐雜的形式婚配的方法來選擇語句履行的分支,這在後續的末節會持續引見。
在switch中,每個case分支都邑被婚配和檢測到,一切case沒有提到的情形都必需應用default症結詞。留意default症結詞必需在一切case的最初。
上面的例子用switch語句來斷定一個字符的類型:
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"
在這個例子中,起首看這個字符是否是元音字母,再檢測是否是子音字母。其它的情形都用default來婚配便可。
不會一向履行
跟C和Objective-C分歧,Swift中的switch語句不會由於在case語句的開頭沒有break就跳轉到下一個case語句履行。switch語句只會履行婚配上的case裡的語句,然後就會直接停滯。如許可讓switch語句加倍平安,由於許多時刻編程人員都邑忘卻寫break。
每個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語句不會同時婚配a和A,它會直接報錯。一個case中可以有多個前提,用逗號,分隔便可:
switch some value to consider {
case value 1,
value 2:
statements
}
規模婚配
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."
元組
case中還可以直接測試元組能否相符響應的前提,_可以婚配隨意率性值。
上面的例子是斷定(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"
和C說話分歧,Swift可以斷定元組能否相符前提。
數值綁定
在case婚配的同時,可以將switch語句中的值綁定給一個特定的常量或許變量,以便在case的語句中應用。好比:
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"
switch語句斷定一個點是在x軸上照樣y軸上,或許在其他處所。這裡用到了婚配和數值綁定。第一種情形,假如點是(x,0)形式的,將值綁定到x上,如許在case語句中可以輸入該值。同理假如在y軸上,就輸入y的值。
Where症結詞
switch語句可使用where症結詞來增長斷定的前提,鄙人面的例子中:
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"
每一個case都由於有where而分歧,第一個case就是斷定x能否與y相等,表現點在斜線y=x上。
4、掌握跳轉語句
在Swift中掌握跳轉語句有4種,讓編程人員更好地掌握代碼的流轉,包含:
continue
break
fallthrough
return
個中continue,break和fallthrough鄙人面具體引見,return語句將在函數一章引見。
continue
continue語句告知一個輪回停滯如今在履行的語句,開端下一次輪回。
留意:在for-condition-increment輪回中,increment增量語句仍然履行,只是略過了一次輪回體。
上面的例籽實現的是去除一個字符串中的空格和元音字母,從而構成一個燈謎:
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"
遍歷字符串的每個字符,當碰到元音字母或許空格時就疏忽,停止下一次輪回,從而獲得了終究的燈謎。
break
break語句將終止全部輪回的履行,可以用在輪回語句中,也能夠用在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是否是一個數字,阿拉伯數字,漢字,拉丁文或許泰文都可以。假如婚配完成,則將possibleIntegerValue賦值。最初在經由過程if語句檢測能否已被賦值,並綁定到integerValue常量上,最初輸入。default語句用來迎接未能被上述case婚配的情形,然則不須要做任何工作,是以直接應用break終止便可。
fallthrough
因為Swift中的switch語句不會主動的由於沒有break而跳轉到下一個case,是以假如須要想C說話中那樣,順次履行每一個case的時刻,就須要用到fallthrough症結詞。
像上面這個例子一樣,default分支終究都邑被履行:
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."
標簽語句
switch和輪回可以相互嵌套,輪回之間也能夠相互嵌套,是以在應用break或許continue的時刻,須要曉得究竟是對哪一個語句起感化。這就須要用到標簽語句。標簽語句的普通情勢以下:
label name: while condition {
statements
}
上面的例子演示了若何應用標簽語句和嵌套的輪回和switch。
仍然采取之前的誰人梯子與蛇的游戲,第一步仍然是設置初始值:
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的嵌套來完成游戲
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!")
在這個代碼中,將游戲的輪回定名為gameLoop,然後在每步挪動格子時,斷定以後能否達到了游戲起點,在break的時刻,須要將全部游戲輪回終止失落,而不是終止switch,是以用到了break gameLoop。異樣的,在第二個分支中,continue gameLoop也指清楚明了須要continue的是全部游戲,而不是switch語句自己。