Swift 5.1 (5) - 控制流

級別: ★☆☆☆☆
標籤:「iOS」「Swift 5.1」「For-In」「標籤語句」「Fallthrough」
做者: 沐靈洛
審校: QiShare團隊php


控制流

For-In循環

使用for-in循環迭代數組git

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
    print("Hello, \(name)!")
}
複製代碼

使用for-in循環迭代字典github

let airports = ["job": "將軍", "age": "16", "name": "zhangfei"]
for (key,value) in airports {
print("\(key)")
print("\(value)")
}
複製代碼

使用for-in循環迭代數值範圍編程

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}
複製代碼

使用for-in循環迭代數值範圍之使用stride(from:to:by :)函數:返回從起始值到結束值(不包括),跳過指定量的序列。從開始值起序列中的每一個連續值都會增長相同範圍的幅度,直到下一個值等於或超過結束值。(以指定間隔迭代特定數值時的序列)。符合Strideable協議的任何類型的值均可以使用此函數,例如整數或浮點類型。swift

for item in stride(from: 0, to: 60, by: 5) {
    print(item, separator: "", terminator: " ")//!< 0 5 10 15 20 25 30 35 40 45 50 55
}
for item in stride(from: 0, to: Double.pi * 2, by: .pi/2) {
     print(item, separator: "", terminator: " ")//!<0.0 1.5707963267948966 3.141592653589793 4.71238898038469
}
複製代碼

使用for-in循環迭代數值範圍之使用stride(from:through:by:)函數:返回從起始值到結束值(可能包括),跳過指定量的序列。(以指定間隔迭代特定數值時的序列)與stride(from:to:by :)函數區別於它可能會包括結束值。數組

for item in stride(from: 0, through: 60, by: 5) {
    print(item, separator: "", terminator: " ")//!< 0 5 10 15 20 25 30 35 40 45 50 55 60
}
for item in stride(from: 0, through: Double.pi * 2, by: .pi/2) {
     print(item, separator: "", terminator: " ")//!<0.0 1.5707963267948966 3.141592653589793 4.71238898038469 6.283185307179586 
}
複製代碼
While循環

Swift提供了兩種while循環:bash

  • while:在每次循環開始時判斷條件。
  • repeat-while:在每次循環結束時判斷條件。

While while循環開始時判斷條件是否成立,若true當即執行方法體,直到條件變爲false時中止執行。微信

let adc = 10
var apc = 0;
while apc < adc {
    apc += 1 //!< 必需要有終止的條件 若 apc < adc 恆成立則程序陷入死循環
    print("條件成立") //10
}
複製代碼

Repeat-While repeat-while循環:while循環的變體,相似於其餘語言中的do-while,先執行單個循環,再考慮循環條件,若爲true繼續重複循環,直到條件爲false中止執行。app

let adc = 10
var apc = 0;
repeat {
    apc += 1
    print("條件成立") //!< 10次
}while apc < adc
複製代碼
條件語句

Ifide

let adc = 20
if adc <= 32 {
    print("adc <= 32")
} else if adc >= 86 {
    print("adc >= 86")
} else {
    print("32 <adc< 86")
}
複製代碼

Switch

let someCharacter: Character = "z"
switch someCharacter {
case "a":
    print("The first letter of the alphabet")
case "z":
    print("The last letter of the alphabet")
default:
    print("Some other character")
}
複製代碼

不隱式貫穿 Swift中的switch語句執行時不會貫穿每一個case。而C和Objective-C中的switch語句須要顯式的break語句,若不添加則會向下貫穿到所匹配項下面的每一個case,並執行。

MyEnumType type = MyEnumType2;
switch (type) {
    case MyEnumType1:
        NSLog(@"MyEnumType1");
    case MyEnumType2:
        NSLog(@"MyEnumType2");
    case MyEnumType3:
        NSLog(@"MyEnumType3");
        
}
/*
 MyEnumType2
 MyEnumType3
 */
複製代碼

Swift中的switch語句只要第一個匹配的switchcase完成,整個switch語句就會完成執行,而不須要顯式的break語句。

let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
    print("The letter A")
default:
    print("Not the letter A")
}
複製代碼

Range匹配
switch語句能夠檢測其判斷的值,是否包含在某個case的範圍內。

let adc = 20
var apc = 0;
var result = ""

switch adc {
case 0...10:
   result = "0...10"
case 11..<20:
    result = "11..<20"
case 20...30:
    result = "20...30"
default:
    result = "beyond of range"
}
print(result)//!< 20...30
複製代碼

元組
switch語句能夠判斷元組的值,是否符合某個case。能夠針對元組不一樣的值或值的間隔範圍來測試元組的每一個元素。或者,使用下劃線字符(通配符)_來匹配任何可能的值。

let tuples : (Int,String,Int) = (404,"not found",-1)
switch tuples {
case (300,"精準匹配1",0):
    print("精準匹配1")
case (0...200,"範圍匹配1",-2...10):
    print("範圍匹配1")
case (_,_,-2...2):
    print("通配符匹配元組前兩個,範圍匹配最後一項")
default:
    print("沒有匹配到")
}

複製代碼

值綁定
switchcase能夠命名它所匹配到的臨時的常量或變量, 以便在case對應的方法中使用。這種行爲稱爲值綁定。

let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
    print("橫座標\(x)")
case (0, let y):
    print("縱座標 \(y)")
case let (x, y):
    print("任何點 (\(x), \(y))")
}
複製代碼

上述switch語句中case(let x,0)匹配y值爲0的任何點,並將點的x值賦給臨時常量xcase(0,let y)匹配x值爲0的任何點,並將點的y值賦給臨時常量ylet(x,y),聲明瞭一個能夠匹配任何值的含有兩個佔位符常量的元組。由於匹配全部可能的剩餘值,因此不須要default case來使switch語句窮舉。
Where
switch語句中case能夠使用where子句來檢查其餘條件。

let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x==y:
    print("匹配到x與y相同的狀況")
case let(x,y) where x == -y:
    print("匹配到x與y爲相反數的狀況")//!<匹配到x與y爲相反數的狀況
default:
    print("沒有匹配的結果")
}
複製代碼

上述示例中switch語句中的case聲明佔位符常量xy,它們暫時從yetAnotherPoint獲取元組值。這些常量用做where子句的一部分,用於建立動態過濾器。僅當where子句的條件對佔位符常量xy的計算結果爲true時,switch語句的case纔會成功匹配當前值。

複合使用

switch語句中如有多個case共享的相同方法體,能夠經過在case以後組合多個模式,每一個模式之間用逗號隔開來表示。多個模式中任一個匹配,則認爲這個case是匹配的。同時case以後的多個模式也能夠多行表示。

let someCharater = "e"
switch someCharater {
case "a","o","e","f":
    print("事例1,匹配成功")//!< log
case "b","v","r","h":
    print("事例2,匹配成功")
default:
    print("未匹配")
}
//複合事例中的值綁定,綁定的值類型必須匹配。case (let x, let y), (0, let x)這種是不被容許的 由於方法體中使用x,y時,若匹配的是 (0, let x)則y 無效。由於相同的值綁定應該存在於全部`case`以後的模式中。
let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let x, 0), (0, let x)://!< 'x' must be bound in every pattern:'x'必須綁定在每一個模式中
    print("匹配成功")
default:
    print("未匹配")
}
複製代碼

switch的case後對應多個模式的複合事例中,每一個模式對應的綁定的值類型必須匹配,而且相同的一組值綁定,如(let x, let y)其中xy稱爲一組值綁定,應該存在於全部case以後的模式中。

控制轉移語句

控制轉移語句經過將控制從一段代碼轉移到另外一段代碼來改變代碼執行的順序。Swift有五個控制轉移語句:

  • continue
  • break
  • fallthrough
  • return
  • throw

continue

continue語句:跳出正在執行的循環語句,當即開始執行下一次循環。

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
    if charactersToRemove.contains(character) {
        continue
    }
    puzzleOutput.append(character)
}
print(puzzleOutput) //!< break下跳出循環,當即開始下一次迭代,輸出爲:grtmndsthnklk
複製代碼

break

break語句:當即結束全部控制流語句的執行。
循環語句中的break:循環語句中使用break,會當即結束循環的執行,並在循環方法體}以後將控制權轉移給後續的代碼。

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
    if charactersToRemove.contains(character) {
        break
    }
    puzzleOutput.append(character)
}
print(puzzleOutput) //!< break下跳出循環不在開始,輸出爲gr
複製代碼

switch語句中的break:在switch語句中使用break,會使switch語句當即結束其執行,並移交控制權。

let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let x, 0), (0, let x):
    print("匹配成功")
default:
    break
}
複製代碼

貫穿(Fallthrough)

若是須要C或Objective-C的貫穿行爲,則能夠使用fallthrough關鍵字。

let describe = 5
var description = ""
switch describe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += "I am"
    fallthrough
case 18:
    description += " bob" //!< case 去掉fallthrough 則輸出I am bob
    fallthrough
default:
    description += " and you?"
}
print(description)//!< I am bob and you?
複製代碼

標籤語句

在Swift中,其餘循環和條件語句中能夠嵌套循環和條件語句,從而建立複雜的控制流結構。可是,循環和條件語句均可以使用break語句過早地結束執行。所以,須要明確break語句終止的循環或條件語句,或明確continue語句應該影響哪一個循環是很是必要的,故會用到標籤語句。

var result = ""
let adc = 30
forLabel : for item in 9...adc {
   switchLabel :switch item {
    case 0...10:
        result += " 0...10"
        break switchLabel //!<swift中break是默認的
    case 11..<20: //!<  如果11..<20區間則跳出for循環,開始下次迭代
        continue forLabel
    case 20://!< 如果20 則當即終止for循環
        result += " 終止for循環"
        break forLabel
    default:
        result += "beyond of range"
    }
}
print(result) //!< 0...10 0...10 終止for循環
複製代碼

提早退出(throw,return)
if語句同樣,guard語句根據表達式的布爾值執行語句。使用guard語句要求條件必須爲true才能執行guard語句以後的代碼。與if語句不一樣,guard語句老是有一個else子句 若是條件爲false,則執行else子句中的代碼。guardelse子句不能向下貫穿,必須使用轉移控制的語句returnthrow才能退出做用域。

//return
let adc = 30
//! guard方法體不能向下貫穿,須要使用`return`或`throw`退出做用域
guard adc > 30 else {
    print("條件不成立")
    return //!< 提早結束了
}
//throw退出做用域
guard adc > 30 else {
    print("條件不成立")
    throw HttpError.authError
}
複製代碼

檢查API可用性
Swift支持檢查API可用性:編譯器使用SDK中的可用性信息來驗證使用的API是否在指定部署目標上可用。確保咱們不會在給定部署目標上使用不可用的API。能夠在ifguard語句中使用可用性條件進行判斷。

if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}
複製代碼

參考資料: swift 5.1官方編程指南


小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

推薦文章:
Xcode11 新建工程中的SceneDelegate
iOS App啓動優化(二)—— 使用「Time Profiler」工具監控App的啓動耗時
iOS App啓動優化(一)—— 瞭解App的啓動流程
iOS WKWebView的基本使用 Swift 5.1 (4) - 集合類型 iOS 解析一個自定義協議
iOS13 DarkMode適配(二)
iOS13 DarkMode適配(一)
2019蘋果秋季新品發佈會速覽
奇舞週刊

相關文章
相關標籤/搜索