Inside Swift’s inout parameters

Some of Swift’s parameters are not constants. This is why you need to know…

Steven Curtis
Jan 7, 2020 · 5 min read

Functions usually pass parameters as constants in Swift, which means that they cannot be changed. If you could, you would need to return the result of your changes somehow. This is where the inout keyword comes into play, and lets you do exactly that.

Difficulty: Beginner | Easy | Normal | Challenging

Prerequisites:

  • Be able to produce a “Hello, World!” iOS application (guide HERE)
  • Have some rudimentary understanding of functions (guide HERE)
  • In a later example, knowledge of named parameters is assumed (guide HERE)
  • Ideally understand the difference between pass by reference and pass by value (guide HERE), although the basics are covered within this article.

Terminology

Constant: A value that can not be amended during the normal execution of a program

inout parameter: A variable that is passed to a function, and if changed within the function the the changes are reflected in the original variable outside the function

in-place: On the spot

Local variable: A variable with limited scope

Mutable: Something that can be changed

Parameter: A special kind of variable referring to a piece of data passed to a function

The idea

You can pass by reference, or pass by value in programming languages. You might wish to do the same when using functions, that is pass a parameter that changes the original value of that parameter rather than making a copy of it.

The function described above as γ1 and γ2 above are functionally identical. The only thing that changes is the function signature for the parameter — one is regular and one is inout I understand, we need the example.

Without further “ado” (if that is a thing)…

We are simply going to put “Name: “ in front of our selected name (which is Steve. If your name is Steve, congratulate yourself for having the correct name. If not, feel free to code replacing the name with another (although then you’ll be doing it wrong).

Speaking of doing it wrong, the following will result in an error:

var name = "Steve"func appendVal(inp: String) {
inp = "Name: " + inp
print (inp)
}
appendVal(inp: name)
print (name)

ahh — inp is a constant, and this means that we must replace it with a local variable.

If we do that, with the following code

var name = "Steve"func appendVal(inp: String) {
var input = "Name: " + inp
print (input) // prints "Name: Steve"
}
appendVal(inp: name)
print (name) // prints "Steve"

We are creating a new variable within appendVal (called input), which is made up of “Name: “ and inp. The final print out line prints “Steve”, that indicates the original name has not been altered by this function.

So the best way to alter the original name is by using an inout parameter. To use this we not only mark the parameter as an inout parameter (with the keyword directly in front of the type in the function signature). There is no longer any reason to create a local variable within the function declaration.

var name = "Steve"func appendVal(inp: inout String) {
input = "Name: " + inp
print (inp) // prints "Name: Steve"
}
appendVal(inp: &name)
print (name) // prints "Name: Steve"

As indicated with the print (name) statement, the original name declaration has now changed to “Name: Steve”. That is, we have changed the original variable by using an inout parameter.

The syntax

We not only label the parameter as inout. We also have to label the value which we will pass with a &.

You can do this for parameters of any type, and you can even mark a parameter as inout and choose not to use it within your function.

However, you must make sure that the inout parameter is mutable.

var num = 4func myFunc(input: inout Int) {
// this function does nothing
}
// called by
myFunc(input: &num)

Any changes that take place to input within the function are reflected in num numoutside the function.

In fact this is also true when we use named parameters (guide on that is HERE), for the following example to increment a Double

var num = 1.0func increment(num initialnum: inout Double) {
initialnum +=1
}
// called by
increment(num: &num)

Limitations

You can’t use a constant when calling the function with an inout parameter. This means that when calling the function you will want to use a var rather than a let.

This means that the following is possible:

var num = 1.0func decrement(num initialnum: inout Double) {
initialnum -= 1
}
// called by
decrement(num: &num)

but the following gives a rather unpleasant error

let num = 1.0func decrement(num initialnum: inout Double) {
initialnum -= 1
}
// called by
decrement(num: &num)

with the error actually being Cannot pass immutable value as inout argument: 'num" is a 'let' constant

which in the IDE looks like the following:

However we should be aware that we can let Xcode automatically fix this for us, changing the num variable from a let to a var variable.

Conclusion

inout parameters allow us to change variables that exist outside a function, from within a function.

This functionality allows us to create functions that change variables in-place, and therefore create much better code that is easier to read.

This is excellent, and is something that you should consider next time you are coding a function.

Happy coding

Want to get in contact? Try the link here:

https://twitter.com/stevenpcurtis

The Startup

Get smarter at building your thing. Join The Startup’s +724K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store