- API fetch
- Array
- Async await
- Class
- Closures
- Computed property
- Concurrency
- Constants
- Data types
- Defer statement
- Dictionary
- Enum
- Escaping closure
- Extension
- For loop
- forEach
- Function
- Generics
- Guard statement
- if let statement
- Inheritance
- inout
- Lazy var
- Operator
- Optionals
- Property observers
- Property wrapper
- Protocol
- String formatting
- String interpolation
- Struct
- Switch statement
- Try catch
- Tuple
- Variables
- While loop
SWIFT
Swift inout
: Syntax, Usage, and Practical Examples
The inout
keyword in Swift allows a function to modify a variable passed as an argument. Normally, function parameters are constants and can’t be changed within the function body. When marked as inout
, a parameter is passed by reference, not by value—meaning changes made to it inside the function will persist after the function returns.
This is useful in scenarios where you want a function to update one or more variables without returning anything.
What Is an inout
Parameter?
An inout
parameter enables direct modification of a variable from within a function. Instead of making a copy, Swift allows the function to access and mutate the original value.
Example:
func increment(number: inout Int) {
number += 1
}
var value = 10
increment(number: &value)
print(value) // Output: 11
The &
prefix is required when passing a variable to indicate that it can be modified by the function.
Syntax Overview
Here’s the general structure:
func modify(param: inout Type) {
// change param
}
var variable = initialValue
modify(param: &variable)
Key Rules:
- Use
inout
before the type in the function signature. - Use
&
when calling the function. - The variable must be declared with
var
, notlet
.
Working with Multiple inout
Parameters
Functions can accept multiple parameters marked as inout
, which is helpful when manipulating two or more values together.
Example:
func swapValues(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var x = 5
var y = 10
swapValues(&x, &y)
print(x, y) // Output: 10 5
This avoids return values and directly swaps variables in place.
When Should You Use inout
?
Use inout
when:
- You need to update a variable’s value inside a function.
- Returning a value isn’t desirable or necessary.
- You’re working with algorithms like sorting, accumulating, or low-level mutation.
However, in many cases, returning a modified value is clearer and aligns better with Swift’s functional style.
Comparing with Return Values
Here’s a contrast between using inout
and returning a new value:
With return:
func double(_ x: Int) -> Int {
return x * 2
}
let result = double(4)
With inout
:
func double(_ x: inout Int) {
x *= 2
}
var num = 4
double(&num)
Both approaches work, but inout
updates the original variable, whereas returning a new value leaves the original unchanged.
Constraints and Limitations
Keep these in mind when using inout
:
- You can’t pass constants, literals, or computed properties.
- Parameters marked as
inout
cannot have default values. - They cannot be captured by escaping closures.
- Only variables (
var
) can be passed—not constants (let
).
These restrictions ensure safe and predictable behavior.
Practical Use Cases
1. Swapping Values
func swap<T>(_ a: inout T, _ b: inout T) {
let temp = a
a = b
b = temp
}
Generic and type-safe, this version can swap values of any type.
2. Accumulating Values
func add(_ value: Int, to total: inout Int) {
total += value
}
var sum = 0
add(5, to: &sum)
add(3, to: &sum)
Useful for running totals or counters.
3. Modifying Struct Properties
Swift structs are value types, so modifying them requires passing the entire instance as inout
.
struct Point {
var x: Int
var y: Int
}
func moveRight(_ point: inout Point, by distance: Int) {
point.x += distance
}
Alternatives to inout
Consider other approaches when mutation isn’t necessary:
- Return values: Prefer when you need one output or want immutability.
- Reference types: Use classes when shared state is required.
- Closures: For deferred execution and captured state.
Use inout
only when it adds clarity or performance benefits.
Best Practices
To use inout
effectively:
- Use it sparingly. Swift encourages immutability and returning new values.
- Name functions clearly to indicate side effects.
- Avoid passing the same variable to multiple
inout
parameters in one call. - Keep
inout
logic short and focused to avoid confusion.
Poor:
func modify(_ a: inout Int) { a = 5 }
Better:
func resetToDefault(_ value: inout Int) {
value = 5
}
Summary
The inout
keyword in Swift allows you to write functions that modify variables directly. It enables pass-by-reference behavior, making it useful for swapping values, updating aggregates, or changing value-type instances like structs.
While powerful, inout
should be used thoughtfully. In many cases, returning a new value is clearer and more in line with Swift’s design philosophy. But when mutation is appropriate, inout
gives you a clean and type-safe way to do it.
Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.