I'm quite new to Kotlin.
I am using IntelliJ and the IDE tells me that this piece of code myList += "abc"
is not the same as this one myList = myList + "abc"
.
In the first case I get a green squiggly line and a warning message that tells me '+=' on a read-only list creates a new list under the hood
. It then gives me a solution to change the list to a mutable type.
On the other hand, the second example works just fine. I've always thought that the difference between these two examples was a syntax issue and not an actual difference in the way data is processed.
Can someone explain why that is?
Is it only Kotlin or all languages work the same way and I just wasn't aware of it?
Thanks for your answers!
You might think that myList += "A"
would be the same as myList = myList + "A"
, like in some other languages. However this is only true in Kotlin if the type of myList
does not overload the plusAssign
operator.
Generally speaking, a += b
gets lowered to a.plusAssign(b)
whenever it is possible to do so. It is only lowered to a = a + b
(aka a = a.plus(b)
) if it there is no suitable plusAssign
operator defined on a
.
See also the documentation here.
MutableList
(actually, all MutableCollection
s) does define a plusAssign
, so assuming myList
is a MutableList
, myList += "A"
lowers to myList.plusAssign("A")
. The implementation of plusAssign
simply calls add
on the collection, and does not create a copy of the list.
On the other hand, myList = myList + "A"
lowers to myList = myList.plus("A")
, which calls plus
, defined on all Collection
s. As you can see from its implementation, it creates a copy of the collection and returns it, which you then assign to myList
.
Side note: you can check what call an operator lowers to by using the "replace overloaded operator with function call" quick action in IntelliJ. Just place the caret on the operator, click on the lightbulb and select the action.