A function packages a piece of work under a name so you can run it whenever you need it, instead of repeating the same lines in several places. Fixing a bug or changing behaviour then happens in one place, and well-named functions make code read like a list of steps.
Swift functions have a distinctive feature: argument labels. When you call a function, each argument is labelled, so calls read like sentences: greet(person: "Ada", from: "London") or move(from: a, to: b). This makes code remarkably self-explanatory, and it's a big part of Swift's style.
In this lesson you'll declare functions with parameters and return values, design clear argument labels, give parameters default values, accept any number of values, return several values at once, let a function change a variable with inout, and store functions in variables.
Declaring and calling functions
func greet(name: String) {
print("Hello, \(name)!")
}
func area(width: Double, height: Double) -> Double {
return width * height
}
greet(name: "Ada")
let room = area(width: 4, height: 3.5)funcdeclares a function; each parameter has a name and a type.-> Doubledeclares the return type, andreturnsends the result back.- A function that returns nothing has no arrow (its return type is
Void). - When the body is a single expression,
returncan be left out:func double(_ n: Int) -> Int { n * 2 }. - Parameters are constants inside the function; you can't reassign them.
Argument labels
Each parameter can have two names: an argument label used when calling, and a parameter name used inside the function:
func move(from start: String, to end: String) {
print("Moving from \(start) to \(end)")
}
move(from: "Leeds", to: "York")Write _ as the label to call without one, which suits functions where the meaning is obvious: func square(_ n: Int) -> Int, called as square(4). Good labels make the call site read naturally: insert(item, at: 0) or remove(at: 2).
Defaults, variadic parameters and tuples
- Default values make parameters optional:
func order(_ item: String, size: String = "medium")can be called asorder("tea")ororder("tea", size: "large"). - A variadic parameter accepts any number of values with
...:func average(_ numbers: Double...), called asaverage(4, 8, 9). Inside,numbersis an array. - Return a tuple to send back several values:
func minMax(_ xs: [Int]) -> (min: Int, max: Int), thenlet r = minMax(scores); r.max.
inout and functions as values
Normally a function receives a copy of each argument. An inout parameter lets it change the caller's variable; the caller writes &:
func addBonus(to score: inout Int) { score += 10 }
var points = 50
addBonus(to: &points) // points is now 60Functions are also values with types like (Int, Int) -> Int. You can store them in variables and pass them to other functions, which leads directly to the closures lesson.
Overloading and a function's full name
Two functions can share a name as long as their parameter labels or types differ. This is called overloading, and Swift picks the right one from the call:
func area(side: Double) -> Double { side * side }
func area(width: Double, height: Double) -> Double { width * height }
print(area(side: 3)) // 9.0
print(area(width: 2, height: 5)) // 10.0Because labels are part of the identity, Swift documentation writes a function's full name with its labels: area(side:) and area(width:height:). You can use that full name to refer to one function without calling it: let calculate = area(width:height:), then calculate(3, 4) gives 12.0. Notice that a stored function is called without labels.
Returning an optional when there may be no answer
Some functions can't always produce a result. Rather than inventing a fake value such as -1, return an optional and send back nil when there's nothing to give:
func firstEven(in numbers: [Int]) -> Int? {
for n in numbers where n % 2 == 0 {
return n // leaves the function straight away
}
return nil
}
print(firstEven(in: [1, 3, 4]) ?? 0) // 4The Int? return type tells every caller that the answer might be missing, and the compiler makes them deal with it. This is the same pattern the standard library uses for Int("42") and array.first.
Swift Functions Syntax
Function forms
func name(param: Type) -> ReturnType { return value }
func square(_ n: Int) -> Int { n * n }
func move(from a: String, to b: String) { }
func order(_ item: String, size: String = "medium") { }
func average(_ xs: Double...) -> Double { }
func minMax(_ xs: [Int]) -> (min: Int, max: Int) { }
func bump(_ n: inout Int) { n += 1 }
bump(&value)Swift Functions Summary
func name(label param: Type) -> ReturnType { }declares a function.- Argument labels make calls readable;
_removes a label. - Single-expression functions can omit return; parameters are constants.
- Default values, variadic parameters (Type...) and tuple returns make functions flexible.
- inout lets a function change the caller's variable, passed with &.
Swift Functions Examples
Each example shows the code, the output it produces and what each part does.
Functions with labels and return values
func celsiusToFahrenheit(_ c: Double) -> Double {
c * 9 / 5 + 32
}
func describe(temperature c: Double) -> String {
let f = celsiusToFahrenheit(c)
let note = c <= 0 ? " (freezing)" : ""
return "\(c)°C is \(f)°F\(note)"
}
print(describe(temperature: 20))
print(describe(temperature: -5))20.0°C is 68.0°F
-5.0°C is 23.0°F (freezing)Line-by-line explanation
- Lines 1 to 3A single-expression function with no argument label, so it's called as celsiusToFahrenheit(c).
- Line 5The label temperature is used by callers; c is used inside.
- Line 11The integer literal 20 becomes a Double because the parameter is a Double.
Defaults and variadic parameters
func formatPrice(_ amount: Double, currency: String = "£") -> String {
let pence = Int((amount * 100).rounded())
return "\(currency)\(pence / 100).\(pence % 100 < 10 ? "0" : "")\(pence % 100)"
}
func average(_ scores: Int...) -> Double {
if scores.isEmpty { return 0 }
return Double(scores.reduce(0, +)) / Double(scores.count)
}
print(formatPrice(5.5))
print(formatPrice(12.05, currency: "$"))
print(average(70, 85, 90))
print(average())£5.50
$12.05
81.66666666666667
0.0Line-by-line explanation
- Line 1currency has a default, so it can be left out.
- Lines 2 to 3Work in whole pence, then build the text: 550 pence becomes 5 and 50.
- Line 6Int... accepts any number of Ints, arriving as an array.
- Line 8reduce(0, +) adds every score, as the closures lesson explains.
Tuple returns and inout
func minMax(_ values: [Int]) -> (lowest: Int, highest: Int)? {
guard let first = values.first else { return nil }
var low = first, high = first
for v in values {
low = min(low, v)
high = max(high, v)
}
return (low, high)
}
func applyDiscount(to price: inout Double, percent: Double) {
price -= price * percent / 100
}
if let range = minMax([62, 91, 75, 48]) {
print("Lowest \(range.lowest), highest \(range.highest)")
}
var price = 80.0
applyDiscount(to: &price, percent: 25)
print(price)Lowest 48, highest 91
60.0Line-by-line explanation
- Line 1The function returns an optional tuple, because an empty array has no minimum.
- Lines 11 to 13inout lets the function change the caller's variable.
- Line 20& marks the argument as something the function may change.
Common Swift Functions Mistakes
Leaving out argument labels
func greet(name: String) { print("Hi \(name)") }
greet("Ada") // error: missing argument label 'name:'greet(name: "Ada")
// or declare it as func greet(_ name: String)Changing a parameter
func double(_ n: Int) -> Int {
n *= 2 // error: left side of mutating operator isn't mutable
return n
}func double(_ n: Int) -> Int { n * 2 }Forgetting & for inout
addBonus(to: points) // error: passing value of type 'Int' to an inout parameter requires explicit '&'addBonus(to: &points)Swift Functions in Real Projects
Functions in Swift apps
Apple's own frameworks are designed around readable argument labels: view.addSubview(button), array.insert(item, at: 0), string.replacingOccurrences(of: "a", with: "b"). Following the same style in your own code makes it feel natural alongside the system APIs, and small, well-named functions are the building blocks of every SwiftUI view and model.
Swift Functions FAQ
What does the underscore before a parameter name mean in Swift?
_ removes the argument label, so callers pass the value without a name. func square(_ n: Int) is called as square(4) instead of square(n: 4). Use it when the function name already makes the argument's meaning obvious.
What is the difference between an argument label and a parameter name?
The argument label is used at the call site, and the parameter name is used inside the function body. In func move(from start: String), callers write move(from: "Leeds") while the body refers to start. If you write only one name, it's used for both.
How do I return multiple values from a Swift function?
Return a tuple, ideally with named parts: func minMax(_ xs: [Int]) -> (min: Int, max: Int). The caller reads result.min and result.max, or unpacks it with let (low, high) = minMax(scores). For more than a few values, a struct is clearer.
Why can't I change a parameter inside a Swift function?
Parameters are constants, which stops a function from quietly changing values the caller relies on. Copy it into a var if you need a working variable, or mark the parameter inout and call with & if you want the caller's variable to change.
What does "result of call is unused" mean in Swift?
Swift warns when you call a function that returns a value and then ignore the result, because that often signals a bug. Assign it to _ with _ = save() to show you meant to ignore it, or mark the function @discardableResult if ignoring the result is normal.
Swift Functions Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the declaration so the function can be called as square(4).
func square( n: Int) -> Int { n * n }
What does this print?
func greet(_ name: String = "friend") -> String { "Hi, \(name)" }
print(greet())
What does this print?
func total(_ xs: Int...) -> Int { xs.reduce(0, +) }
print(total(1, 2, 3, 4))
How do you call func move(from start: String, to end: String)?
What does an inout parameter allow?
Swift Functions Quiz
5 questions to check what you learned.
Which keyword declares a function in Swift?
- function
- func
- fun
- def
What does
->introduce in a function declaration?- A parameter
- The return type
- A label
- A comment
What is an argument label?
- The function's name
- The parameter's type
- The name callers write before an argument, like from: in move(from: a)
- A comment
When can a function leave out the return keyword?
- Never
- When it returns Void
- When it has no parameters
- When its body is a single expression
Can you assign a new value to a normal parameter inside a function?
- No, parameters are constants; copy them to a var or use inout
- Yes
- Only Ints
- Only with default values