Closures: pass behaviour as a value
Closures: pass behaviour as a value
A teacher may sort names alphabetically or by length. Instead of writing a separate collection type for each policy, supply a closure that decides the ordering. A closure packages executable behaviour and can capture values from its surrounding scope.
What you’ll learn
- Supply a closure as a sorting policy.
- Define a consistent tie-break and recognize capture lifetime issues.
Closures: pass behaviour as a value in the example
Compare lengths
A teacher may sort names alphabetically or by length.
Compare lengthsResolve a tie
Closure parameters and return values can be inferred from the function expecting them.
Resolve a tieNew sorted array
Diya and Noor each have four characters, so the explicit alphabetical tie-break orders them consistently.
New sorted array
How closures: pass behaviour as a value works
Closure parameters and return values can be inferred from the function expecting them. sorted(by:) asks whether one element should precede another. A trailing closure is written after the call’s parentheses. Capturing an external variable can make later behaviour depend on changing state, so consider its lifetime and meaning.
Work through closures: pass behaviour as a value
Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.
Swift · complete program
let names = ["Saira", "Diya", "Noor"]
let ordered = names.sorted { first, second in
first.count == second.count ? first < second : first.count < second.count
}
print(ordered)Expected output
["Diya", "Noor", "Saira"]Follow the execution
Diya and Noor each have four characters, so the explicit alphabetical tie-break orders them consistently. Saira has five and follows them. The ternary operator chooses one expression from its Boolean condition. sorted returns a new array and does not mutate names.
Try this program in the Swift compiler. Paste the complete source above.
Practice: Closures: pass behaviour as a value
Your task: Why supply an alphabetical tie-break for equal-length names?
Swift · complete program
let names = ["Saira", "Diya", "Noor"]
let ordered = names.sorted { first, second in
first.count == second.count ? first < second : first.count < second.count
}
print(ordered)Worked answer
It makes the ordering policy explicit for ties rather than relying on assumptions about their retained order. The closure states both the primary comparison and the secondary comparison.
Write a consistent ordering policy
A sorting comparison must be consistent; returning true for both directions or changing its rule during sorting gives an invalid policy. Escaping closures can outlive the function call that stores them and can create ownership cycles when capturing class instances.
Check your decision
Write a consistent ordering policy
It makes the ordering policy explicit for ties rather than relying on assumptions about their retained order. The closure states both the primary comparison and the secondary comparison. A sorting comparison must be consistent; returning true for both directions or changing its rule during sorting gives an invalid policy.
Further reading: official Swift language guide.
Reaching the recap and completing the quizzes are separate milestones.