Ray Wenderlich Functions and Types Course - Part 3

Here we go! Getting back into a routine with this! Straight on to continue closures...

Start Time - 19:45

Closure Syntax

Writing closures inline is one of the main benefits. Using shorter syntax can make them easier but can also make it more complicated to figure out...

This old chestnut I've seen before.

let longClosure = { (a: Int, b: Int) -> Int in
    return a * b
    
}

longClosure(4, 3)

let noParameterTypes = { (a, b) -> Int in
    a * b
    
}

let noReturnTypes: Operate = { (a, b) in
    a * b

}

let shortClosure: Operate = { $0 * $1 }

noParameterTypes(4, 3)
noReturnTypes(4, 3)

shortClosure(4, 3)

The difference is that there was a type alias with the closure signature there. 

Here is a point about trailing closures - 

// --------------------------------------
func printResult(_ a: Int, _ b: Int, _ operate: Operate) {
  print(operate(a, b))
}
// --------------------------------------


printResult(4, 3, { $0 * $1 })

printResult(4, 3) { $0 * $1 }

The function was already made - we have unnamed parameters and different positions of the closing bracket. Both work!

Challenge!


This was tough!!!

But I got there! Took some figuring out. 

// --------------------------------------
let copyLines = { (offense: String, repeatCount: Int) -> Void in
  print( String(repeating: "I must not \(offense).", count: repeatCount) )
}
// --------------------------------------

// TODO: Write solution here

typealias Copy = (String, Int) -> Void


let noParameterCopyLines: Copy = { offense, repeatCount -> Void in
      print( String(repeating: "I must not \(offense).", count: repeatCount) )

}

let noParameterOrReturnCopyLines: Copy = { offense, repeatCount in
      print( String(repeating: "I must not \(offense).", count: repeatCount) )

}

let noParameterNames: Copy = { ($0, $1)
      print( String(repeating: "I must not \($0).", count: $1) )

}

Type alias was my idea - thought this was better than putting the signature each time. I'm learning! Catie didn't even mention that!

OK, last one has an even easier solution!

let noParameterNames: Copy = {
      print( String(repeating: "I must not \($0).", count: $1) )

}

For this, the $0 and $1 are already used in the print line. So not needed again!

forEach and Map


I saw this in Laurie's course. It does the same thing!

Map is specifically for collections. 

for price in prices {
    print(price)
}

prices.forEach { (price) in
    print(price)
}

prices.forEach { print($0) }

Neat!

Map....

var emptyArray: [Double] = []

for price in prices {
    emptyArray.append(price * 0.9)
}

emptyArray

let salePrices = prices.map { $0 * 0.9 }

salePrices

Yes map is definitely better than doing a for loop. 

let priceLabels = salePrices.map { (price) -> String in
    String(format: "%.2f", price)
}


And this is an extra thing - transforming, which the syntax for got simplified after pressing enter. Then using the format bit and price...that bit was confusing.  But good stuff!

Summary - 

  • Closures can be written in various forms. You can remove parameter names, types, return types...you can use other shorthand elements like $ too!
  • Type alias is great for getting the signature written just once
  • *Trailing closures - still unsure of these
  • forEach can be used instead of for loops; use of $0 inside can keep them really simple
  • Map is a way of transforming a collection

Finish Time - 20:31 (46 minutes; some interruptions!)

Hard stuff today but useful. Still not totally au fait with closures but getting there. Will get in another session on Thursday and keep this momentum going!


Comments

Popular posts from this blog

*Xcode Project Entry 2* F1 Quiz - part 1

Angela Yu Course Part 10 (up to lesson 112)

Angela Yu Xcode 12 Course - Part 7 (lectures 74 to 79)