Search code examples
arrayskotlinextension-function

Kotlin - Val cannot be reassigned , but can be reassigned by accessing from index?


I have these two functions where i am trying to modify the elements. One of them compiles and other says 'val cannot be reassigned'. What is the difference between the following functions? Why does one compile and the other does not?

The one that compiles

fun <T> Array<T>.mapInPlace2(transform: (T) -> T) {
for (i in this.indices) {
    this[i] = transform(this[i])
}
}

The one that says

Val cannot be reassigned

fun <T> Array<T>.mapInPlace1(transform: (T) -> T) {
for (i in this) {
    i = transform(i);
}
}

Solution

  • Similiarly to how function parameters are final in Kotlin, so are the variables used in for loops. Essentially, writing down...

    for (i in array) {
        ...
    }
    

    ... is the equivalent of doing this in Java:

    for (final int i : array) {
        ...
    }
    

    This helps catch some common errors, in this case - if the compiler allowed you - you'd be reassigning this local variable that just contains a reference to the real element, without changing the array. In Java terms, you'd be doing this:

    for (int i : array) {
        i = transform(i);
    }
    

    This new value of i is unused, it doesn't change the array itself, and it will be immediately overwritten by the value of the next element when the loop comes around.