Control Flow
loop
- while
- for-in
- repeat while
condition branch
- if
switch
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 = 1for _ 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 = 60let interval = 5for tickMark in stride(from: 0, to: minutes, by: interval) { // render the mark every 5 minutes. // 0, 5, 10, ... , 50, 55}// closed rangefor 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 = 0while 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 = 0while a < 0 { print(a) a += 1}// will not printrepeat { print(a) a += 1}while a < 0// will print 0
Condition
If
var a = 4if 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 = 40var 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 thecase
can always access a value fordistance
.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 in 1...10 { if n % 2 == 0 { continue } nums.append(n)}print(nums)
resule
[1, 3, 5, 7, 9]
### Break```swiftvar nums: [Int] = []for n in 1...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.```swiftlet n = 5switch n {case 1: print("one")case 2: print("I want to break") break print("two") // it won't do thiscase 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 = 5switch n {case 5: print("five") fallthrough // go on the code in the switchdefault: 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 = 1var sum = 0aLoop: 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 = 1var sum = 0aLoop: 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
9It continue the outside while loop.
---## Early ExitA `guard` must have else clause after it.It’s to exit early.```swiftfunc 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```swiftif #available(iOS 10, macOS 10.12, *) { } else { // Fall back to earlier iOS and macOS APIs}```