Most parameters are copied as values. They never affect the original call site. But inout parameters are different—they share a memory location.
With inout, changes in the called method are reflected in the variables at the call site. The variables are not separate. This enables some code techniques.
Let us begin with this example. The size()
method receives an inout parameter of type Int
. We call size()
by passing it a reference to the "x" variable.
size()
func
modifies the inout parameter to equal 10. After it returns, "x" still equals 10.func size(x: inout Int) { // Set out parameter. x = 10 } // Value equals 0. var x = 0 print(x) // Call size with inout argument. size(x: &x) // Now variable equals 10. print(x)0 10
Sometimes a complex problem may require recursion. With an inout argument, we can share a variable among many recursive calls.
x()
func
use an inout depth argument. When depth reaches 10, no more calls occur.func
.func x(depth: inout Int) { // Increase depth value. depth += 1 if (depth < 10) { // Use recursion to increase depth again. x(depth: &depth) } } // Count depth of recursion. var depth = 0 x(depth: &depth) print(depth)10
Here is an error that may occur with inout arguments. We cannot use an immutable let value as an argument when an inout argument is needed.
func test(name: inout String) { } // Cannot use let keyword with inout. let name = "" test(name: &name)Cannot pass immutable value as inout argument: 'name' is a 'let' constant
With inout parameters in Swift, we can use multiple return values. This is an alternative to returning a tuple or modifying a class
argument.
We must use the ampersand when passing arguments to a method that receives an inout argument. The ampersand means "address of" as opposed to "value of."
For Swift 3, we place inout after the argument's label. In previous versions of Swift the inout keyword was before the label.
The inout keyword is powerful. It provides an alternative to tuples for complex methods with many return values. It may make some code more complex. Use it with care.