標籤:匹配 axis rto 字串 pen ios print ons 並且
// 控制流程
// swift 提供了多種控制流程結構,包括可以多次執行的 while 迴圈,基於特定條件選擇執行不同分支的 if, guard 和 switch 語句,還有控制流程程跳轉到其它代碼位置的 break 和 continue 語句
// swift 還提供了了 for-in 迴圈,用來更簡單地遍曆數組(array), 字典(dictionary), 區間(range), 字串(String) 和其它序列類型
// swift 的switch 語句比C語言中更加強大, 在C語言中,如果某個 case 不小心漏寫了 break, 這個 case 就會貫穿至下一個 case swift 無需寫 case ,也無需寫 break 所以不會發生貫穿的情況, case 還可以匹配很多不同的模式,包括間隔匹配, 元組(tuple) 和轉換到特定類型. swift 語句的case 中匹配的值還可以綁定成臨時變數或常量, 在 case 中使用, 也可以用 where 來描述更加複雜的匹配條件
// for-In 迴圈
// 你可以使用 for-in 迴圈來遍曆一個集合中的所有元素, 例如數字範圍,數組中的元素或者字串中的字元
for index in 1...5 {
print("\(index) times 5 is \(index*5)")
}
// 上面的例子中, index 是一個每次迴圈遍曆開始時被自動複製的常量. 這種情況下, index 在使用前不需要聲明, 字需要將它包含在迴圈的聲明中,就可以對其進行隱式聲明,而無需 使用 let 關鍵字聲明
// 如果你不需要區間序列內每一項的值, 你可以使用 (_) 替代變數名來忽略這個值
// (_)(替代迴圈的變數) 能夠忽略當前值, 並且不提供迴圈遍曆時對值的訪問
let names = ["Anna","Alex","Brian","Jack"]
for name in names {
print("Hello, \(names)")
}
// 你也可以通過遍曆一個字典來訪問它的索引值對,遍曆字典時候.字典的每項元素會以 (key, value) 元組的形式返回, 你可以在 for-in 迴圈中使用顯式的常量名稱來解讀 (key, value) 元組
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}
// 字典元素的遍曆順序和插入順序可能不同, 字典的內容在內部是無序的, 所以遍曆元素時不能保證順序
// While
// While 迴圈從計算一個條件開始, 如果條件為 true ,會重複運行一段語句, 直到條件變為 false, 才會結束跳過
// Repeat-While
// While 迴圈的另一種形式, 它和 while 的區別是在判斷迴圈條件之前 ,先執行一次迴圈的代碼塊, 然後重複迴圈知道條件 false
// Swift 語言的 repeat-while 迴圈和其它語言的 do-while 迴圈是類似的
//repeat{
//
//}while condtion
// 條件陳述式
// 根據特定條件執行特定的代碼通常是十分有用的,當錯誤發生時, 你可能想運行額外的代碼, 或者,當值太大或者太小的時候,向使用者顯示一條訊息, 要實現這些功能, 你就需要使用條件陳述式
// swift 提供兩種類型的條件陳述式, if 語句 和 switch 語句, 通常,當條件較為簡單而且可能 的情況橫少時 , 使用 if 語句, 而 switch 語句更適用於條件比較複雜的,有更多排列組合的時候, 並且在 switch 在需要用到模式比對的情況下回更有用
// If
// if 語句最簡單的形式就是 只包含一個條件 ,當改條件為 true 的時候, 才會執行相關代碼
var temperatureInFahrenHeit = 30
if temperatureInFahrenHeit <= 32 {
print("It‘s very cold, Consider wearing a scarf")
}
// 當然, if 語句允許二選一執行, 叫做 else 從句, 也就是當條件為 FALSE 時 ,執行 else 語句
// Switch
// Switch 語句會嘗試把某個值與若干個模式進行 匹配, 根據第一個匹配成功的模式, switch 語句會執行對應的代碼,當有可能的情況較多時, 通常用 switch 語句替換 If 語句
// switch 語句最簡單的形式就是把某個值與一個或若干個相同類型的值做比較
switch 1 {
case 1:
print(1)
default:
print("no value")
}
// switch 語句由多個 case 構成,每個有 case 關鍵字開始,為了匹配某些特定的值, swift 提供了幾種 方法來進行更複雜的模式比對,
// 與 if 語句類似, 每一個 case 嗾使代碼執行的一條分支, switch 語句會決定哪一條分支應該被執行, 這個流程被稱作更具給定的值切換
// switch 語句必須是完備的,這就是說,每一個可能的值都必須至少有一個 case 分支預支對應, 在某些不可能涵蓋所有值的情況下, 你可以使用預設 (default) 分支來涵蓋其他所有沒有對應值的情況, 這個預設分支必須在 switch 語句的最後面
// 例如
let someCharacter: Character = "z"
switch someCharacter {
case "a":
print("The first letter of the alphbet")
case "z":
print("The last letter of the alphabet")
default:
print("Some other character")
}
// 不存在隱式的貫穿
// 與 C 和 OC 中的 switch 語句不同,在 swift 中,當匹配 case 分支的代碼執行完畢後, 程式會終止 switch 語句,而不會繼續執行下一個 case 分支, 這就是說, 不需要再 case 分支中顯式地使用 break 語句, 這使得 switch 語句更加安全, 更易用, 也避免了 break 漏寫而產生的錯誤
// 注意 : 雖然在swift 中 break 不是必須的, 但你依然可以在 case 分支中的代碼執行完畢之前使用 break 跳出
// 每一個分支 case 都必須包含至少一條語句, 分支下面不可為空
//let anotherCharacter: Character = "a"
//switch anotherCharacter {
//case "a": // 無效,這個分支下面沒有語句
//case "A":
// print("The letter A")
//default:
// print("Not the letter A")
//}
//// 這段代碼會報編譯錯誤
// 不像 C語言裡的 switch 語句,在swift 中, switch 語句 不會一起匹配 "a" 和 "A", 相反的,上面的代碼會引起編輯器錯誤, case "a": 不包含任何可執行語句, 這就避免了意外地從一個case 分支貫穿到另外一個, 使得代碼更加安全, 也更直觀
// 為了讓單個 case 同時匹配 a 和 A ,可以將這兩個值合成一個複合匹配,並且用逗號隔開:
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
print("The letter A")
default:
print("Not the letter A")
}
// 輸出 "The letter A
// 注意 : 如果想要顯式貫穿 case 分支, 請使用 fallthrough 語句
// 區間匹配
// case 分支的模式也可以是一個值的區間,
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
var naturalCount: String
switch approximateCount {
case 0:
naturalCount = "no"
case 1..<5:
naturalCount = "a few"
case 5..<12:
naturalCount = "several"
case 12..<100:
naturalCount = "dozens of"
case 100..<1000:
naturalCount = "hundreds of"
default:
naturalCount = "many"
}
print("There are \(naturalCount) \(countedThings).")
// 輸出 "There are dozens of moons orbiting Saturn."
// 元組
// 我們可以使用元組在同一個 switch 語句中測試多個值, 元組中的元素可以是值, 也可以是區間, 另外,使用底線(_) 來匹配所有可能的值
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0):
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// 輸出 "(1, 1) is inside the box"
// 值綁定 (Value Bindings)
// case 分支允許將匹配的值綁定到一個臨時的常量或變數, 並且在 case 分支體內使用 -- 這種行為稱為值綁定, 因為匹配的值在 case 分支體內, 與臨時的常量或變數綁定
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
print("on the x-axis with an x value of \(x)")
case (0, let y):
print("on the y-axis with a y value of \(y)")
case let (x, y):
print("somewhere else at (\(x), \(y))")
}
// Where
// case 分支的模式可以使用 where 語句來判斷額外的條件
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y)) is just some arbitrary point")
}
// 輸出 "(1, -1) is on the line x == -y"
// 複合匹配
// 當多個條件可以使用同一種方法來處理時候,可以將這幾種可能放在同一個 case 後面, 並且用逗號隔開, 當 case 後面的任意一種模式比對的時候, 這條分支就會被匹配,並且,如果匹配列表過長,還可以分行書寫
let somesCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(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":
print("\(someCharacter) is a consonant")
default:
print("\(someCharacter) is not a vowel or a consonant")
}
// 輸出 "e is a vowel"
// 複合匹配同樣可以包含綁定值, 複合匹配裡面所有的匹配模式, 都必須包含相同的的值綁定,並且沒一個綁定都必須擷取到相同類型的值,這保證了, 無論複合匹配中的那個模式發生了匹配,分支體內的代碼,都能擷取到綁定的值,並且綁定的值都有一樣的類型
// 控制轉移語句
// 控制轉移語句改變你的代碼的執行順序,通過它可以實現代碼的跳轉, swift 有五種控制轉移的語句:
// continne
// break
// fallthrough
// return
// throw
// continue
// continue 告訴一個迴圈立即停止本次迴圈,重新開始下次迴圈,就好像說 ‘本次迴圈我已經執行完了‘, 但是並不會離開整個迴圈體
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput.characters {
switch character {
case "a", "e", "i", "o", "u", " ":
continue
default:
puzzleOutput.append(character)
}
}
print(puzzleOutput)
// break
// break 語句會立即結束整個控制流程的執行, 當你想要更早的結束一個switch 代碼塊或者一個迴圈體的時候, 你可以使用 break
// 迴圈語句中的 break
// 當在一個迴圈體中使用 break 的時候, 會立即中斷改迴圈體的執行, 然後跳到表示迴圈體結束的大括弧 (}) 後的第一行代碼, 不會再有本次迴圈的代碼被執行, 也不會再有下次的迴圈發生
// Switch 中的 break
// 當在一個 switch 中使用 break 的時候, 會立即中斷改 switch 代碼塊的執行, 並且跳到表示 switch 代碼塊結束的大括弧 (}) 後的第一行代碼
// 這種特性可以被用來匹配或者忽略一個或者多個分支, 因為 swift 的 switch 需要包含所有的分支並且不允許有空的分支存在, 有事為了你的意圖更加明顯, 需要特意匹配或者忽略某個分支, 那麼當你想忽略某個分支時, 可以在改分支內寫上 break 語句, 當那個分支被匹配到時, 分支內的 break 語句立即結束 switch 代碼塊
// 注意 : 當一個 switch 分支緊緊包含注釋時, 會被編輯時錯誤, 注釋不是代碼語句而且也不能讓 switch 分支達到被忽略的效果, 應該使用 break來忽略某個分支
// 貫穿
// swift 中的 switch 不會從上一個 case 分支落入到下一個 case 分支中, 相反,只要第一個匹配到的 case 分支完成了它需要執行的語句,整個 switch 代碼塊完成了它的執行, 相比之下, C語言要求你顯式地插入 break 語句到每個 case 的結尾來阻止自動落入到 下一個 case 分支中, swift 的這種避免落入下一個分支的特性一位整個他的 switch 功能要比 C語言 的更加的清晰和可預測, 可以避免無意識執行多個 case 分支從而引發的錯誤
// 如果你確實需要 C語言的貫穿的特性, 你可以在每個需要改特性的 case 分支中使用 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."
}
print(description)
// 注意 : fallthrough 關鍵字不會檢查下一個將會落入執行的 case 分支的匹配條件, fallthrough 雞蛋地使得代碼繼續串連到下一個 case 中的代碼, 這個和 C語言標準 switch 語句特性是一樣的
// 帶標籤的語句
// 在 swift 中. 你可以在迴圈體和條件陳述式中嵌套迴圈體和添加語句來創造複雜的控制流程結構, 並且,迴圈體和條件陳述式都可以使用 break 語句來提前結束整個代碼塊
// 為了實現這個目的, 你可以使用標籤 (statement label) 來標記一個迴圈體或者條件陳述式, 對於一個條件陳述式, 你可以使用 break 加標籤的方式,來結束這個被標記的語句, 對於一個迴圈語句,你可以使用 break 或者 continue 加標籤嗎來結束或者繼續這條被標記語句的執行
// 聲明一個帶標籤的語句是通過在該語句的關鍵字的同一行前面放置一個標籤, 作為這個語句的前置關鍵字 ,並且該標籤後面跟隨一個冒號, 下面的是一個 while 迴圈體的標籤文法,同樣的規則適用於所有的迴圈體和條件陳述式
// 提前退出
// 像 if 語句一樣. guard 的執行取決於一個運算式的布爾值, 我們可以使用 guard 語句來要求條件必須為真時, 以執行 guard 語句後的代碼 , 不同於 if 語句, 一個 guard 語句總是有一個 else 從句.如果條件不為真則執行 else 從句中的代碼
// 如果 guard 語句的條件被滿足, 則執行 guard 語句大括弧後面的代碼, 將變數或者常量的可選綁定 guard 語句的條件 ,都可以保護 guard 語句後面的代碼
// 如果條件不被滿足, 在 else 分支 上的代碼就會被執行,這個分支必須轉移控制以退出 guard 語句出現的程式碼片段, 它可以用控制轉移語句如 : return ,break, continue,或者 throw , 或者調用一個不返回的方法或函數
// 相比於可以實現同樣功能的 if 語句, 按需使用 guard 語句會提升我們代碼的可讀性,它可以使你的代碼連貫的被執行而不需要將它包在 else 塊中, 它可以使你在緊鄰條件判斷的地方,嗎處理違規的情況
// 檢測 API 的可用性
// swift 內建支援檢查 API 可用性, 這可以確保我們不會再當前部署的機器上, 不小心使用了停用 API
// 編輯器使用 SDK 中的可用資訊來驗證我們代碼中的使用的所有的 API 在項目指定的部署目標上是否可用, 如果我們嘗試使用一個停用 API, swift 會在編輯是報錯
// 我們在 if 或 guard 語句中使用 可用性條件 (availability condition) 去有條件的執行一段代碼, 來運行時判斷調用的 API 是否可用, 編輯器使用從可用性條件陳述式中擷取的資訊去驗證,在這個代碼塊中是可用
if #available(iOS 10, macOS 10.12, *) {
}else{
}
// 以上可用性條件指定, 在 iOS 中, if 語句的代碼塊僅僅在 iOS 10 以及更高的系統下運行; 在 MacOS 中, 僅在 macOS 10.12 以及更高的版本才會運行, 最後一個參數 (*) 是必須的, 用於指定在所有其它平台中, 如果版本高於你的裝置指定的最低版本, if 語句的代碼塊也會執行
// 在它一般的形式中, 可用性條件使用了一個平台名字和版本的列表, 平台名字可以是 iOS, macOS, watchOS 和 tvOS , 除了指定像 iOS 8 這樣的主要版本號, 我們可以指定 iOS 8.3 以及 macOS 10.10.3 的子版本號碼
Swift 學習- 06 -- 控制流程