Swift clip: First class functions
Welcome to Swift Clips — a new series of shorter videos showcasing interesting and useful Swift tips and techniques. In this first episode we’ll take a look at first class functions, which is a language feature that enables us to use functions in really powerful ways.
Sample code
Adding a series of views as subviews of another view:
let view: UIView = ...
let subviews: [UIView] = [button, label, imageView]
// Using a closure
subviews.forEach { subview in
view.addSubview(subview)
}
// Using first class functions
subviews.forEach(view.addSubview)
Converting an array of strings into URL
values:
let strings = ["swiftbysundell.com", "apple.com"]
// Using a closure
let urls = strings.compactMap { string in
URL(string: string)
}
// Using first class functions
let urls = strings.compactMap(URL.init)
Sorting an array of Int
values in descending order:
let scores: [Int] = [9, 20, 2, 1, 5]
// Using a closure
let highScores = scores.sorted(by: { $0 > $1 })
// Using first class functions
let highScores = scores.sorted(by: >)
Applying a value to a closure, to avoid the classic “weak self dance”:
// A view controller that currently captures 'self' weakly, in
// order to call a method on a 'productManager' property object:
class ProductViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
buyButton.handler = { [weak self] in
guard let self = self else {
return
}
self.productManager.startCheckout(for: self.product)
}
}
}
// Introducing a 'combine' function for applying a value to
// any function or closure:
func combine<A, B>(
_ value: A,
with closure: @escaping (A) -> B
) -> () -> B {
return { closure(value) }
}
// Using our new combine function:
class ProductViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
buyButton.handler = combine(product,
with: productManager.startCheckout
)
}
}