Swift Learning Summary: Control Flow

Swift Learning Summary: Control Flow
文章图片

Control Flow

  • loop
    • while
    • for-in
    • repeat while
  • condition branch
    • if
    • switch
      【Swift Learning Summary: Control Flow】where
    • guard
  • control transfer statements
    • break
    • continue
    • fallthrough
    • return
    • throw
Loop For-In Loops
var pets = ["cat", "dog"] for pet in pets { print(pet) } for index in 0..<2 { print(pets[index]) }// if we don't need the value from the 0..<2, use the underscore to ignore the value. var n = 1 for _ in 0..<2 { print(n) n += 1 }var words = [11: "fine", 2: "happiness"] for (key, word) in words { print("\(key): \(word)") }

Stride Function
let minutes = 60 let interval = 5 for tickMark in stride(from: 0, to: minutes, by: interval) { // render the mark every 5 minutes. // 0, 5, 10, ... , 50, 55 }// closed range for tickMark in stride(from: 0, through: minutes, by: inerval { // render the mark every 5 minutes. // 0, 5, 10, ... , 50, 55, 60 }

The for-in can be only use to the object which conform to the Sequence protocol.
While
var a = 0 while a < 10 { print(a)// 0 to 9 a += 1 }

Repeat While
The content that repeat while enclose with {} will run at least once.
var a = 0 while a < 0 { print(a) a += 1 } // will not printrepeat { print(a) a += 1 }while a < 0 // will print 0

Condition If
var a = 4 if a < 5 { // smaller than 5 } else if a > 5 { // bigger than 5 } else { // equal to 5 }

Switch
The body of each case must contain at least one executable statement.
No Implicit Fallthrough: no need to write ‘break’ in each case, switch do only one case.
var s: String = "as" switch s { case "aa", "AA": print("not the target") case "as": print("yes") default: print("I don't know") }

Interval Matching
var a = 40 var amount: String? switch a { case ..<0: amount = nil case 0: amount = "no" case 1...10: amount = "few" case 11..<50: amount = "some" case 50..<100: amount = "many" default: amount = "much" }

Tuples
  • Use underscore as a wildcard pattern.
  • The point (0, 0) would match case (0, 0) first, and so all other matching cases would be ignored.
let point = (1, 1) switch point { case (0, 0): print("It's origin") case (_, 0): print("It's on x axis") case (0, _): print("It's on y axis") case (-2...2, -2...2): print("It's in the box") default: print("Out of box") }

Value Bindings
  • The case can name value or values from the matched test, for use in the body of the case.
  • It can only use in tuple test.
let point = (2, 0) switch point { case (let x, 0): print("(\(x),0) is on x axis") case (0, let y): print("(0, \(y) is on y axis") case let(x, y): print("(\(x), \(y)) not on axis") }

Where
  • Add a condition for the value or values from the test.
let point = (2, -2) switch point { case let(x, y) where x == y: print("(\(x), \(y)) is on the line y = x") case let(x, y) where x == -y: print("(\(x), \(y) is on the line y = -x") case let(x, y): print("(\(x), \(y)) others") }

Compound Cases
  • Multiple cases can compounded into one.
  • The pattern can be written over multiple lines.
let c = "a" switch c { case "a", "e", "i", "o", "u": print("It's 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("It's a consonant.") default: print("It's not an alphabet.") }

  • Compound with tuple binding
    Every pattern in a case must include the temporary object(distance), so the code in the body of the case can always access a value for distance.
    let point = (1, 0) switch point { case (0, let distance), (let distance, 0): print("point is on the axis, distance \(distance)") default: print("point isn't on the axis") }

    ---
    ## Control Transfer Statements
    ### Continue
    Tells a loop to stop what it’s doing and start again at the beginning of the next iteration through the loop.
    var nums: [Int] = [] for n in1...10 { if n % 2 == 0 { continue } nums.append(n) } print(nums)

    • resule
      [1, 3, 5, 7, 9]
### Break```swift var nums: [Int] = [] for n in1...10 { if n == 5 { break } nums.append(n) } print(nums) ```- result[1, 2, 3, 4]Break in a switch- comments aren’t statement, use a `break` when the case body is empty.```swift let n = 5 switch n { case 1: print("one") case 2: print("I want to break") break print("two")// it won't do this case 3: print("three") default: break } ```

Fallthrough
In Swift , oneswitch only execute one case . If we want to execute multiple cases, use the fallthrough .
let n = 5 switch n { case 5: print("five") fallthrough// go on the code in the switch default: print("believe it or not") break }

Labeled Statements
The break and continue can only affect the current for, while, switch, repeat while. So when we want to break or continue the outside loop or switch, we can use the labeled statements.
  • break
    var a = 1 var sum = 0 aLoop: while a < 10 { while a < 5 { if a == 3 { a += 5 break aLoop } a += 1 print("add a: \(a)") } print(a) a += 1 }

    • result
      add a: 2
      add a: 3
  • continue
    var a = 1 var sum = 0 aLoop: while a < 10 { while a < 5 { if a == 3 { a+=5// now the a is 8 continue aLoop } a += 1 print("add a: \(a)") } print(a) a += 1 }

    • result
      add a: 2
      add a: 3
      8
      9
      It continue the outside while loop.
---## Early ExitA `guard` must have else clause after it. It’s to exit early.```swift func play(ball: String?) { guard let str = ball else { print("no ball") return// the guard's else can't fall through, here we use the return to end the excution. } print(str)// it's available after the guard's statement. }play(ball: nil) ```## Checking API Availability```swift if #available(iOS 10, macOS 10.12, *) {} else { // Fall back to earlier iOS and macOS APIs } ```

    推荐阅读