Motivation
Binding associated values from an enum case to a local variable is verbose and often repetitive. For example:
enum Fruit {
case apple(diameter: Double, color: String)
case orange(diameter: Double)
case grapefruit(diameter: Double)
case banana
var circumference: Double? {
// Repeated code to pull associated value; encourages copy-pasting
switch self {
case .apple(let diameter, _): return diameter * PI
case .orange(let diameter): return diameter * PI
case .grapefruit(let diameter): return diameter * PI
case .banana: return nil
}
}
var color: String {
switch self {
case .apple(_, let color): return color
case .orange: return "orange"
case .grapefruit: return "pink"
case .banana: return "yellow"
}
}
}
Proposal
Bind associated values to local variables $0, $1, ... $n, where n is the number of associated values for that case.
Conceptually similar to a few existing features:
Anonymous Closure Arguments
[1,2,3].map { $0 + 1 }
Implicit variable binding in catch
block
do {
try someRiskyOperation()
} catch {
print(error)
}
Implicit variable binding for property setters and observers
class Person {
init(name: String) {
self.name = name
}
var name: String {
willSet { print("setting name: \(newValue)") }
didSet { print("set name: \(oldValue)") }
}
}
Example usage
enum Fruit {
case apple(diameter: Double, color: String)
case orange(diameter: Double)
case grapefruit(diameter: Double)
case banana
var circumference: Double? {
switch self {
case .apple: return $0 * PI
case .orange: return $0 * PI
case .grapefruit: return $0 * PI
case .banana: return nil
}
}
var color: String {
switch self {
case .apple: return $1
case .orange: return "orange"
case .grapefruit: return "pink"
case .banana: return "yellow"
}
}
}