Swift Function Parameters
Introduction
Parameters are a fundamental aspect of functions in Swift. They allow you to pass data into functions, making your code more flexible and reusable. In this tutorial, we'll explore how Swift handles function parameters, from basic usage to more advanced parameter types.
Function parameters in Swift are more sophisticated than in many other programming languages, offering features like external parameter names, default values, variadic parameters, and in-out parameters. Understanding these concepts will help you write cleaner, more expressive code.
Basic Function Parameters
At its simplest, a function parameter is a value that you pass to a function when you call it. Let's start with a basic example:
func greet(name: String) {
print("Hello, \(name)!")
}
// Calling the function
greet(name: "Alex")
Output:
Hello, Alex!
In this example, name
is a parameter of type String
. When we call the function, we provide a value for this parameter.
Parameter Labels and Argument Labels
Swift uses a unique system of parameter labels that makes function calls more expressive and readable:
func greet(person name: String) {
print("Hello, \(name)!")
}
// Calling the function
greet(person: "Sarah")
Output:
Hello, Sarah!
Here, person
is the external parameter name (used when calling the function), and name
is the internal parameter name (used within the function). This allows for more readable function calls while maintaining clear internal variable names.
Omitting Parameter Labels
You can also omit parameter labels by using an underscore:
func multiply(_ a: Int, by b: Int) -> Int {
return a * b
}
// Calling the function
let result = multiply(5, by: 3)
print(result)
Output:
15
In this example, the first parameter doesn't require a label when calling the function, making the call more natural.
Default Parameter Values
Swift allows you to provide default values for parameters, which are used if a value isn't provided when calling the function:
func greet(person: String, formally: Bool = false) {
if formally {
print("Good day, \(person).")
} else {
print("Hey, \(person)!")
}
}
// Calling with default parameter
greet(person: "Taylor")
// Overriding default parameter
greet(person: "Taylor", formally: true)
Output:
Hey, Taylor!
Good day, Taylor.
Default parameters are particularly useful for functions with many optional settings.
Variadic Parameters
Variadic parameters accept zero or more values of a specified type. You declare a variadic parameter by inserting three period characters (...
) after the parameter's type:
func calculateAverage(of numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
// Calling with different numbers of arguments
let avg1 = calculateAverage(of: 5.0, 10.0, 15.0)
let avg2 = calculateAverage(of: 2.5, 4.5)
print("Average 1: \(avg1)")
print("Average 2: \(avg2)")
Output:
Average 1: 10.0
Average 2: 3.5
Variadic parameters are treated as arrays inside the function body.
In-Out Parameters
Normally, parameters in Swift are constants. If you want to change a parameter's value and have that change persist after the function call, you can use an in-out parameter:
func swapValues(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var x = 5
var y = 10
print("Before swap: x = \(x), y = \(y)")
swapValues(&x, &y)
print("After swap: x = \(x), y = \(y)")
Output:
Before swap: x = 5, y = 10
After swap: x = 10, y = 5
To use an in-out parameter:
- Mark it with the
inout
keyword in the function declaration - Pass the variable with an ampersand (
&
) before its name when calling the function - The variable must be a variable, not a constant (declared with
var
, notlet
)
Real-World Applications
Building a Shopping Cart Calculator
Let's create a more complex example that demonstrates how different parameter types work together:
func calculateTotal(items prices: Double...,
applyDiscount discount: Double = 0.0,
addTax tax: Bool = true,
taxRate: Double = 0.08,
inout finalAmount: Double) {
// Calculate subtotal from all items
var subtotal = 0.0
for price in prices {
subtotal += price
}
// Apply discount if any
let discountAmount = subtotal * discount
let afterDiscount = subtotal - discountAmount
// Apply tax if needed
let taxAmount = tax ? afterDiscount * taxRate : 0.0
let total = afterDiscount + taxAmount
// Set the final amount
finalAmount = total
// Print receipt
print("===== Receipt =====")
print("Subtotal: $\(String(format: "%.2f", subtotal))")
if discount > 0 {
print("Discount: $\(String(format: "%.2f", discountAmount)) (\(Int(discount * 100))%)")
}
if tax {
print("Tax: $\(String(format: "%.2f", taxAmount)) (\(Int(taxRate * 100))%)")
}
print("Total: $\(String(format: "%.2f", total))")
print("==================")
}
var amountDue: Double = 0.0
calculateTotal(items: 10.99, 5.99, 3.50,
applyDiscount: 0.1,
inout: &amountDue)
print("Amount to pay: $\(String(format: "%.2f", amountDue))")
Output:
===== Receipt =====
Subtotal: $20.48
Discount: $2.05 (10%)
Tax: $1.47 (8%)
Total: $19.90
==================
Amount to pay: $19.90
This example demonstrates several parameter types:
- Variadic parameter for item prices
- Default parameters for discount, tax settings, and tax rate
- An in-out parameter to return the final amount
Creating a Flexible Text Formatter
Here's another real-world example using various parameter types:
func formatText(text: String,
bold: Bool = false,
italic: Bool = false,
color: String = "black",
size: Int = 12) -> String {
var formattedText = text
if bold {
formattedText = "**\(formattedText)**"
}
if italic {
formattedText = "*\(formattedText)*"
}
let styleAttributes = [
"color: \(color)",
"font-size: \(size)px"
].joined(separator: "; ")
return "<span style=\"\(styleAttributes)\">\(formattedText)</span>"
}
// Different ways to call the same function
let text1 = formatText(text: "Hello World")
let text2 = formatText(text: "Important Notice", bold: true, color: "red", size: 16)
let text3 = formatText(text: "Emphasized", italic: true, color: "blue")
print(text1)
print(text2)
print(text3)
Output:
<span style="color: black; font-size: 12px">Hello World</span>
<span style="color: red; font-size: 16px">**Important Notice**</span>
<span style="color: blue; font-size: 12px">*Emphasized*</span>
This example shows how default parameters can create highly flexible functions that can be called with different numbers of arguments.
Summary
Swift function parameters are powerful tools that allow you to create flexible, reusable, and expressive code. In this tutorial, we've covered:
- Basic parameter syntax
- Parameter labels and argument labels
- Default parameter values
- Variadic parameters
- In-out parameters
- Real-world applications combining these concepts
By mastering these parameter types, you'll be able to design more intuitive and flexible functions in your Swift applications.
Exercises
To reinforce your learning, try these exercises:
-
Create a function that calculates the area of different shapes based on a
shape
parameter and other required parameters. -
Write a function that formats a name with options for showing the first name first or last name first, including or excluding middle names, and adding titles.
-
Create a temperature conversion function that can convert between Celsius, Fahrenheit, and Kelvin using default parameters.
-
Design a function using in-out parameters to modify an array in place, like sorting or filtering.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)