Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicitly unwrapped optional made immutable

Tags:

swift

Why is it that I cannot mutate an implicitly unwrapped optional variable?

Here is a short example the reproduces the issue:

With Array

var list: [Int]! = [1]
list.append(10) // Error here

Immutable value of type '[Int]' only has mutating members named 'append'

With Int

var number: Int! = 1
number = 2
number = 2 + number
number += 2 // Error here

Could not find an overload for '+=' that accepts the supplied arguments

like image 782
drewag Avatar asked Jun 06 '14 22:06

drewag


2 Answers

Because the way you are trying to mutate them is by mutating the values (which are immutable) instead of mutating the var.

In Swift value types are immutable. All and always.

Mutation is not a mutation of the value, it's a mutation of the variable that contains the value.

In the case of the Int, the += operator gets a structure on the left and an Int on the right, and it cannot add a structure to an int.

In the case of the Array the append is a mutating member. But it's being invoked on an immutable value that is not directly stored in a variable. It can only operate on values that are directly stored in a variable (which is what makes them mutable: the fact that they are stored in a variable. They are not really mutable, the variable is).

like image 127
Analog File Avatar answered Oct 21 '22 13:10

Analog File


Update:

This has been fixed in Xcode Beta 5 with one small caveat:

var list: [Int]! = [1]
list.append(10)

var number: Int! = 1
number! += 2
number += 2 // compile error

The array works as expected, but it seems that right now the integer still requires an explicit unwrap to allow using +=


Currently, this is just the nature of Optionals (whether implicitly unwrapped or not). The unwrap operator returns an immutable value. This is likely to be fixed or a better solution will be provided in the future.

The only way around it for now is to wrap the array in a class:

class IntArray {
    var elements : [Int]
}
like image 37
drewag Avatar answered Oct 21 '22 13:10

drewag