Lesson 10 / 25
Functions and Argument Labels
Write functions with argument labels, defaults, inout and variadic parameters.
Readable call sites
Swift functions have argument labels that make calls read like sentences: move(from: a, to: b). Each parameter has an external label and an internal name (func send(_ message: String, to recipient: String)), and _ omits the label. Parameters can have default values, and variadic parameters accept several values (numbers: Int...). Parameters are constants by default; inout parameters let a function modify a caller's variable, passed with & at the call site. Functions are first-class: they can be stored in variables, passed as arguments and returned, with types written like (Int, Int) -> Int. Functions can be nested, and overloaded by parameter labels and types. Return values can be omitted in single-expression bodies. Mark functions whose results should not be ignored with @discardableResult only when ignoring is fine; by default the compiler warns about unused results. Follow the Swift API Design Guidelines: clarity at the point of use is more important than brevity.
Labels make calls read clearly
External labels describe each argument at the call site; internal names are used inside the function.
Labels, defaults, variadics and inout
Call sites read naturally; inout changes the caller's variable.
func transfer(_ amount: Double, from source: String, to destination: String, note: String = "") -> String {
"Moved \(amount) from \(source) to \(destination)" + (note.isEmpty ? "" : " (\(note))")
}
print(transfer(500, from: "savings", to: "current"))
print(transfer(200, from: "current", to: "wallet", note: "festival"))
func average(of numbers: Double...) -> Double {
numbers.isEmpty ? 0 : numbers.reduce(0, +) / Double(numbers.count)
}
print(average(of: 70, 85, 91))
func applyDiscount(to price: inout Double, percent: Double) {
price -= price * percent / 100
}
var price = 1000.0
applyDiscount(to: &price, percent: 10) // price is now 900.0
let operation: (Double, Double) -> Double = (+) // functions are values
print(operation(2, 3))Name for the call site
Read the call aloud: remove(at: index) and insert(item, at: 0) read like English. If a call needs a comment to explain its arguments, better labels usually remove that need.
Quick check: How do you let a function modify a caller's variable in Swift?
- Use a var parameter
- Return a pointer
- Declare the parameter inout and pass the argument with &
- It is not possible
Answer
Declare the parameter inout and pass the argument with & — inout parameters write their final value back to the caller's variable.