Swift Functions
A function is a reusable block of code with a name. Instead of writing the same instructions over and over, you write them once in a function and call that function whenever you need it. Think of a function like a vending machine: you press a button (call the function), it performs its job, and gives you a result.
Defining a Basic Function
func greet() {
print("Hello from Swift!")
}
greet() // Output: Hello from Swift!The keyword func starts a function. The name follows (greet). The parentheses hold parameters. The curly braces wrap the body.
Functions With Parameters
Parameters let you pass information into a function.
func greet(name: String) {
print("Hello, \(name)!")
}
greet(name: "Alice") // Output: Hello, Alice!
greet(name: "Bob") // Output: Hello, Bob!Multiple Parameters
func add(a: Int, b: Int) {
print("\(a) + \(b) = \(a + b)")
}
add(a: 4, b: 6) // Output: 4 + 6 = 10Functions That Return a Value
Use the arrow -> followed by a type to declare what the function returns. Use return to send the value back.
func square(of number: Int) -> Int {
return number * number
}
let result = square(of: 5)
print(result) // Output: 25Diagram: Function Anatomy
func square (of number: Int) -> Int {
| | | | |
keyword name parameter arrow return
label+name type
return number * number
|
return value
}
Argument Labels vs Parameter Names
Swift separates the external label (what callers see) from the internal name (what the function uses inside).
func drive(from origin: String, to destination: String) {
print("Driving from \(origin) to \(destination)")
}
drive(from: "New York", to: "Boston")
// Output: Driving from New York to BostonThe caller reads from: and to:. The function body uses origin and destination. This makes call sites read like plain English.
Omitting the External Label
Use an underscore to allow callers to skip the label.
func double(_ number: Int) -> Int {
return number * 2
}
print(double(7)) // Output: 14Default Parameter Values
A parameter with a default value becomes optional at the call site.
func greet(name: String, emoji: String = "👋") {
print("\(emoji) Hello, \(name)!")
}
greet(name: "Alice") // Output: 👋 Hello, Alice!
greet(name: "Bob", emoji: "🎉") // Output: 🎉 Hello, Bob!Variadic Parameters
A variadic parameter accepts any number of values of the same type.
func sum(_ numbers: Int...) -> Int {
var total = 0
for n in numbers {
total += n
}
return total
}
print(sum(1, 2, 3)) // Output: 6
print(sum(10, 20, 30, 40)) // Output: 100inout Parameters
Normally, functions work with copies of values. An inout parameter lets the function modify the original variable directly.
func doubleInPlace(_ value: inout Int) {
value *= 2
}
var myNumber = 5
doubleInPlace(&myNumber)
print(myNumber) // Output: 10The ampersand & at the call site signals that you are passing the variable by reference.
Functions Returning Multiple Values (Tuples)
A function can return multiple values packaged in a tuple.
func minMax(array: [Int]) -> (min: Int, max: Int) {
var min = array[0]
var max = array[0]
for value in array {
if value < min { min = value }
if value > max { max = value }
}
return (min, max)
}
let result = minMax(array: [3, 1, 7, 4, 2])
print("Min: \(result.min), Max: \(result.max)")
// Output: Min: 1, Max: 7Nested Functions
Functions can live inside other functions. Inner functions are only visible to the outer function.
func buildGreeting(for name: String) -> String {
func addEmoji(_ text: String) -> String {
return text + " 🎉"
}
let base = "Hello, \(name)!"
return addEmoji(base)
}
print(buildGreeting(for: "Swift"))
// Output: Hello, Swift! 🎉Summary
Functions package reusable logic behind a name. They accept parameters (with labels for readability), return values using ->, and support features like default values, variadic inputs, inout modification, and tuple returns. Writing good functions keeps code organized, testable, and easy to read.
