Blog / March 1, 2019 / 2 mins read / By Suneet Agrawal

‘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.

Comments