Functions and Closures
TrailLog shows total distance, the longest hike, and a list sorted by date. Each is a small piece of logic you want to name and reuse. Functions give logic a name; closures let you hand logic to someone else, like a sort.
The rule
A function is named reusable code; a closure is the same idea without a name.
A Swift function has argument labels that make calls read like sentences:
func totalDistance(of hikes: [Hike], inMiles: Bool = false) -> Double {
let km = hikes.reduce(0) { $0 + $1.distanceKm }
return inMiles ? km * 0.621 : km
}
totalDistance(of: journal) // default: kilometres
totalDistance(of: journal, inMiles: true)ofis the label used at the call site;hikesis the parameter name used inside._as a label means "no label":func format(_ km: Double)is calledformat(8.5).= falsegives a default value, so the argument can be left out.-> Doubleis the return type. No arrow means the function returns nothing.
A closure is a block of code you can store in a variable or pass as an argument. The full form is { (parameters) -> ReturnType in body }:
let byDate = journal.sorted(by: { (a: Hike, b: Hike) -> Bool in
return a.date > b.date
})Swift lets you trim that, step by step, because the types are already known from sorted(by:):
journal.sorted { a, b in a.date > b.date } // types inferred, trailing closure
journal.sorted { $0.date > $1.date } // shorthand argument namesWhen a closure is the last argument, it can go after the parentheses — a trailing closure. $0, $1 are shorthand names for the first and second parameters.
The shortcut
To read a closure, find in (or the $ names): left of in is the input, right of it is the work.
The line
let long = journal.filter { $0.distanceKm > 10 }
The trap is mixing up label and name: inside totalDistance(of hikes:) you write hikes, never of.
Drills
Answer fast — trust the rule.
Given func format(_ km: Double) -> String, which call is correct?
Inside func totalDistance(of hikes: [Hike]) -> Double, how do you refer to the array?
What does [3, 12, 7].filter { $0 > 5 } return?
Which line is a trailing closure?
Remember
- A function is named, labelled, reusable code; a closure is an unnamed block you can pass around.
- Read closures around
in: inputs on the left, work on the right;$0is the first input. - Trap: the argument label is for callers, the parameter name is for the body.
