In-Out Parameters In Swift Functions

Updated on June 18th, 2022

⏱ Reading Time: 4 mins

When coding in Swift, we usually don’t need to mutate the arguments that we provide to functions, and then make these changes visible back to the call site. We mostly use them as inputs to calculations or other expressions, and if necessary, we return some value from functions. But even if we tried to modify the parameter values, that would trigger a compile-time error, as parameter values are treated as constants, and therefore, they can’t be mutated.

To make my point about what I’m actually talking about, think of the following function that doubles the given number:

This simplistic example will work just fine, as it takes the parameter value as an input, it doubles it, it assigns the new value to another constant declared in the function, and then returns that value back to the caller. The next code though is not going to work:

Xcode will complain with the following error:

– Left side of mutating operator isn’t mutable: ‘number’ is a ‘let’ constant

That says what I mentioned at the beginning; parameter values are considered to be constants, and they cannot be modified like variables can.

But, what if we really want to mutate the original parameter value? It might be sometimes much more suitable to do that, instead of returning a value from the function. Thankfully, we can, using in-out parameter values!

Mutating a parameter value

There is a certain way to let a function know that a parameter value should be treated as a variable and not as a constant. That is to use the inout keyword right before the parameter’s data type.

Say, for example, that we are implementing a function to calculate the factorial number of 10 (10!). Instead of returning the factorial from the method though, we’ll update the parameter value. See how the inout is used right next:

This will do its job perfectly, and the value that will be given as argument to factorial(result:) will eventually get updated with the calculated result value. But marking the parameter with the inout keyword is not the only requirement; upon calling the function we must prefix the variable’s name that we provide as argument with the ampersand (&) symbol.

In practice, we can call the factorial(result:) function like so:

See the ampersand symbol right before the number argument, but also note that number is a variable (declared with var) and not a constant. Only variables can be provided as arguments to inout parameters.

You can try the above in an Xcode playground, and to verify that number gets changed after having called the factorial(result:), just print its value:

In-Out parameters can co-exist with normal parameters

It might be sometimes necessary to have both in-out parameters and normal parameters together in a function. This is allowed to do without having to deal with any kind of restrictions that limit the number of parameters or their order.

Suppose that we want to update the factorial(result:) function, and make it possible to receive as argument the number that we want to calculate the factorial for:

That new version of the factorial method now has two parameter values, with the first being a normal one, and the second being the in-out result. Also, the function’s body has been updated, as the zero number is a bit special.

We can now provide the number that we want to calculate the factorial for to factorial(number:result:) function as argument:

Multiple In-Out parameters can exist in a function

The previous examples contained just one inout parameter in the demonstrated function. However, we can have as many of them as necessary, and the following example shows that. The next function swaps two String values using in-out parameters:

Swapping is a quite standard technique and does not require any further explanation. To make use of the above, we’ll initialize two String variables which we’ll pass as arguments prefixed with ampersand symbol:

Printing this and that after having swapped them verifies that their values have changed as expected.

Conclusion

In-out parameters serve a specific purpose, and that is to mutate the original values supplied as arguments to functions or methods. Unless it’s a desired effect, think twice before using them; mutability in multiple places can be the reason of potential unwanted troubles and bugs in code. Working with immutable values as much as possible, and modify only those that are really necessary where it’s actually necessary, can help avoid this kind of problems. However, do not hesitate to use in-out parameters if they’re better suited to what you’re coding, as they are a great programming tool if used properly; and now you know how.

Thank you for reading, take care! ????

Stay Up To Date

Subscribe to my newsletter and get notifiied instantly when I post something new on SerialCoder.dev.

    We respect your privacy. Unsubscribe at any time.