Swift: Pass array by reference?
Structs in Swift are passed by value, but you can use the inout
modifier to modify your array (see answers below). Classes are passed by reference. Array
and Dictionary
in Swift are implemented as structs.
For function parameter operator we use:let
(it's default operator, so we can omit let) to make a parameter constant (it means we cannot modify even local copy);var
to make it variable (we can modify it locally, but it wont affect the external variable that has been passed to the function); andinout
to make it an in-out parameter. In-out means in fact passing variable by reference, not by value. And it requires not only to accept value by reference, by also to pass it by reference, so pass it with &
- foo(&myVar)
instead of just foo(myVar)
So do it like this:
var arr = [1, 2, 3]
func addItem(_ localArr: inout [Int]) {
localArr.append(4)
}
addItem(&arr)
print(arr) // it will print [1, 2, 3, 4]
To be exact it's not just a reference, but a real alias for the external variable, so you can do such a trick with any variable type, for example with integer (you can assign new value to it), though it may not be a good practice and it may be confusing to modify the primitive data types like this.
For Swift versions 3-4 (XCode 8-9), use
var arr = [1, 2, 3]
func addItem(_ localArr: inout [Int]) {
localArr.append(4)
}
addItem(&arr)
print(arr)
Define yourself a BoxedArray<T>
that implements the Array
interface but delegates all functions to a stored property. As such
class BoxedArray<T> : MutableCollection, Reflectable, ... {
var array : Array<T>
// ...
subscript (index: Int) -> T {
get { return array[index] }
set(newValue) { array[index] = newValue }
}
}
Use the BoxedArray
anywhere you'd use an Array
. Assigning of a BoxedArray
will be by reference, it is a class, and thus changes to the stored property, through the Array
interface, will be visible to all references.