Functions
Functions are self-contained chunks of code that perform a specific task.
Defining and Calling Functions
Use the func keyword to define a function.
func greet() {
print("Hello, Pirate!")
}
greet() // Calling the functionParameters and Return Values
Functions can accept input parameters and return a result. You define a parameter inside the parentheses by writing its name followed by a colon and its data type. If the function gives back a result, you declare that return type after the parentheses using an arrow -> followed by the data type.
func add(a: Int, b: Int) -> Int {
return a + b
}
let result: Int = add(a: 5, b: 10)If a function does not need to give anything back, it technically returns a special type called Void. You can either write out -> Void explicitly, or just leave the arrow and return type off entirely.
It is important to remember that passing is not sharing for functions. When you pass a variable into a function, Swift copies its value rather than sharing the original reference. Function parameters are constants by default, meaning you cannot modify the original input data from inside the function.
Argument Labels (The "Two-Name" System)
In most languages, a function's parameter has one name. You use that name when you call the function, and you use that same name inside the function.
Swift does something unique: parameters can have two names
- Argument Label: Used outside the function (when you call it).
- Parameter Name: Used inside the function (when you write the code).
Syntax:
func functionName(argumentLabel parameterName: Type)The Magic Underscore (_): If you want to omit the label entirely when calling the function, you use underscore as the argument label. Example:
func sayHello(to person: String, _ city: String) {
print("Hello \(person) from \(city)!")
}
sayHello(to: "John", "London") // "to" label is used, city's label is omittedDefault Parameter Values
You can provide a default value for any parameter.
func greet(name: String = "Guest") {
print("Hello, \(name)")
}
greet() // "Hello, Guest"
greet(name: "Pirate") // "Hello, Pirate"Variadic Parameters
A variadic parameter allows a function to accept zero or more values of a specified type.
func sum(_ numbers: Int...) -> Int {
var total = 0
for number in numbers {
total += number
}
return total
}
print(sum(1, 2, 3, 4, 5)) // 15Parameter Rules & Edge Cases
Argument Order is Fixed
Unlike some languages (like Python), Swift does not allow you to pass arguments in a different order than they were defined, even if you use the argument labels.
func move(x: Int, y: Int) { ... }
move(x: 10, y: 20) // Correct
move(y: 20, x: 10) // ERROR: Argument 'x' must precede 'y'Default Parameter Placement
Place parameters with default values at the end of a function's parameter list. This ensures that the essential required arguments appear first. It also guarantees that function calls remain consistent and easy to read whether or not you provide the optional values.
Variadic Parameter Placement
A function can have one or more variadic parameters. However, any parameter immediately following a variadic parameter must have an explicit argument label to prevent the compiler from getting confused about where the list of values ends.
func multiSum(_ numbers: Int..., suffix: String) {
print("\(numbers.reduce(0, +)) \(suffix)")
}
multiSum(1, 2, 3, suffix: "total") // ValidMixing Underscores and Labels
Parameters with omitted labels (using _) can be freely mixed with parameters that have explicit labels. It is very common to omit the label for the first argument while requiring it for subsequent ones.
func update(_ value: Int, for key: String) {
print("Updating \(key) to \(value)")
}
update(10, for: "score") // First is omitted, second is labeledImplicit Returns
If a function body is a single expression, you can omit the return keyword.
func multiply(a: Int, b: Int) -> Int {
a * b // Implicit return
}Scope
Scope determines where in your code a specific variable can be accessed.
Local Scope: Variables defined inside a function are local to that specific function. They cannot be seen or used from the outside.
Global Scope: Variables defined outside of any function or structure have global scope. You can access them from anywhere in your file or project.
Closure Scope: Swift supports nested functions. A function defined inside another function can access and use variables from its outer enclosing function.
Documentation Notation (_:)
You will often see Swift functions written as name(_:) in documentation (e.g., print(_:) or insert(_:)).
- The underscore
_means the argument label is omitted when calling the function. - The colon
:represents the position of the argument value.
This notation allows you to see the "shape" of the function call without writing out a full example.
