英文:
Difference between myList += "A" vs myList = myList + "abc" in Kotlin?
问题
I'm quite new to Kotlin.
我对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"
.
我正在使用IntelliJ,而IDE告诉我,这段代码 myList += "abc"
与 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 a read-only list creates a new list under the hood
。然后它提供了一个解决方案,将列表更改为可变类型。
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?
这只是Kotlin还是所有语言都以相同的方式工作,只是我不知道吗?
Thanks for your answers!
感谢你的回答!
英文:
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!
答案1
得分: 3
你可能认为 myList += "A"
与 myList = myList + "A"
在某些其他语言中是相同的。然而,在 Kotlin 中只有在 myList
的类型不重载 plusAssign
运算符时才成立。
一般来说,只要可能的话,a += b
会被转化为 a.plusAssign(b)
。只有在 a
上没有定义适合的 plusAssign
运算符时,才会被转化为 a = a + b
(也就是 a = a.plus(b)
)。
另请参阅此处的文档。
MutableList
(实际上,所有 MutableCollection
)确实定义了一个 plusAssign
,所以假设 myList
是一个 MutableList
,myList += "A"
会被转化为 myList.plusAssign("A")
。plusAssign
的实现只是在集合上调用 add
,而不会创建列表的副本。
另一方面,myList = myList + "A"
会被转化为 myList = myList.plus("A")
,它调用了所有 Collection
上定义的 plus
。从其实现中可以看到,它创建了集合的副本并返回,然后将其分配给 myList
。
附注:你可以使用 IntelliJ 中的“用函数调用替换重载的运算符”快捷操作来查看运算符被转化成什么调用。只需将光标放在运算符上,单击小灯泡,然后选择该操作。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论