‘inout’ in Swift


Recently, while working with swift I came up with a use case where I need to modify the variable passed as an argument to a function. Eventually, all the variables passed to a function are of an immutable type which cannot be changed which is similar to a let variable. If it’s a class object, you cannot create a new object but you can manipulate the properties of that class object or you can call any function with that object.
  
class Employee {
var name : String
var age : Int
init(name: String, age: Int){
self.name = name
self.age = age
}
}

func changeEmployeeData(emp : Employee){
employee.name = "Suneet"
employee.age = 25
}

let employee = Employee(name: "Random", age : 10)
print(employee.name) //Random
print(employee.age) //10
changeEmployeeData(emp : employee)
print(employee.name) //Suneet
print(employee.age) //25

Now the problem occurs when your argument is of primitive data type, you simply can’t change the value.
  
var variable: Int = 1
func changeNumber (num: Int) {
num = 2
print(num)
}
changeNumber(num : variable)
It will show the error cannot assign to value: ‘num’ is a ‘let’ constant which is self-explanatory.
We can’t modify the parameter passed as an argument as those are of let type.

Now, what if I want to modify this value?


inout to the rescue.
You can use inout where it passes the parameter as a reference.
  
var variable: Int = 1
func changeNumber (num:inout Int) {
num = 2
print(num) // 2
}

changeNumber(num : &variable)
You need to add inout before the datatype of the variable and an & while passing the parameter.

Coming back to our previous example where we just changed the properties value, what if we want to assign it a new object itself.
  
class Employee {
var name : String
var age : Int
init(name: String, age: Int){
self.name = name
self.age = age
}
}

func changeEmployeeData(emp : Employee){
emp = Employee(name: “Suneet”, age: 25)
}

var employee = Employee(name: “Random”, age : 10)
print(employee.name)
print(employee.age)
changeEmployeeData(emp : employee)
print(employee.name)
print(employee.age)
This will show us the same compilation error cannot assign to value: ‘emp’ is a ‘let’ constant.

Instead, we can use the inout after which we can modify the object.
  
func changeEmployeeData(emp :inout Employee){
emp = Employee(name: “Suneet”, age: 25)
}

var employee = Employee(name: “Random”, age : 10)
print(employee.name) //Random
print(employee.age) //10

changeEmployeeData(emp : &employee)
print(employee.name) //Suneet
print(employee.age) //25

The only thing to keep in mind

while using the inout is, as we pass the address of the variable/object, it modifies the actual object also.