Welcome to FutureAppLaboratory

v=(*^ワ^*)=v

Learning Swift Part 7 - Closure & Enumerations

| Comments

===== Full Notes =====

Closure

  • Closure Expression Syntax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

    { (parameters) -> return type in
        statements
    }

    func backwards(s1: String, s2: String) -> Bool {
        return s1 > s2
    }
    var reversed = sorted(names, backwards)
    // reversed is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

    // This is the same closure
    reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )
  • Inferring Type From Context
1
    reversed = sorted(names, { s1, s2 in return s1 > s2 } )
  • Implicit Returns from Single-Expression Closures
1
    reversed = sorted(names, { s1, s2 in s1 > s2 } )
  • Shorthand Argument Names
1
    reversed = sorted(names, { $0 > $1 } )
  • Operator Functions
1
    reversed = sorted(names, >)
  • Trailing Closure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    func someFunctionThatTakesAClosure(closure: () -> ()) {
        // function body goes here
    }

    // here's how you call this function without using a trailing closure:

    someFunctionThatTakesAClosure({
        // closure's body goes here
    })

    // here's how you call this function with a trailing closure instead:

    someFunctionThatTakesAClosure() {
        // trailing closure's body goes here
    }

    // Sample

    let digitNames = [
        0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
        5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
    ]
    let numbers = [16, 58, 510]

    let strings = numbers.map {
        (var number) -> String in
        var output = ""
        while number > 0 {
            output = digitNames[number % 10]! + output
            number /= 10
        }
        return output
    }
    // strings is inferred to be of type [String]
    // its value is ["OneSix", "FiveEight", "FiveOneZero"]
  • Capturing Value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    func makeIncrementor(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementor() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementor
    }

    let incrementByTen = makeIncrementor(forIncrement: 10)

    incrementByTen()
    // returns a value of 10
    incrementByTen()
    // returns a value of 20
    incrementByTen()
    // returns a value of 30

    let incrementBySeven = makeIncrementor(forIncrement: 7)
    incrementBySeven()
    // returns a value of 7

    incrementByTen()
    // returns a value of 40
  • Closures Are Reference Types
1
2
3
    let alsoIncrementByTen = incrementByTen
    alsoIncrementByTen()
    // returns a value of 50

Enumerations

  • Enumeration Syntax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    enum CompassPoint {
        case North
        case South
        case East
        case West
    }

    enum Planet {
        case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
    }

    var directionToHead = CompassPoint.West

    // Can be shortened

    directionToHead = .East
  • Matching Enumeration Values with a Switch Statement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    directionToHead = .South
    switch directionToHead {
    case .North:
        println("Lots of planets have a north")
    case .South:
        println("Watch out for penguins")
    case .East:
        println("Where the sun rises")
    case .West:
        println("Where the skies are blue")
    }
    // prints "Watch out for penguins"

    let somePlanet = Planet.Earth
    switch somePlanet {
    case .Earth:
        println("Mostly harmless")
    default:
        println("Not a safe place for humans")
    }
    // prints "Mostly harmless"
  • Associated Values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    enum Barcode {
        case UPCA(Int, Int, Int, Int)  // a Barcode
        case QRCode(String)            // a QRCode
    }

    var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)

    productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

    switch productBarcode {
    case .UPCA(let numberSystem, let manufacturer, let product, let check):
        println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
    case .QRCode(let productCode):
        println("QR code: \(productCode).")
    }
    // prints "QR code: ABCDEFGHIJKLMNOP."

    // Can be shortened

    switch productBarcode {
    case let .UPCA(numberSystem, manufacturer, product, check):
        println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
    case let .QRCode(productCode):
        println("QR code: \(productCode).")
    }
    // prints "QR code: ABCDEFGHIJKLMNOP."
  • Raw Values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    enum ASCIIControlCharacter: Character {
        case Tab = "\t"
        case LineFeed = "\n"
        case CarriageReturn = "\r"
    }

    enum Planet: Int {
        case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
    }

    let earthsOrder = Planet.Earth.toRaw()
    // earthsOrder is 3

    let possiblePlanet = Planet.fromRaw(7)
    // possiblePlanet is of type Planet? and equals Planet.Uranus

    let positionToFind = 9
    if let somePlanet = Planet.fromRaw(positionToFind) {
        switch somePlanet {
        case .Earth:
            println("Mostly harmless")
        default:
            println("Not a safe place for humans")
        }
    } else {
        println("There isn't a planet at position \(positionToFind)")
    }
    // prints "There isn't a planet at position 9"

Comments