我刚到Kotlin。
我正在使用IntelliJ,IDE告诉我这段代码myList += "abc"
与这段代码myList = myList + "abc"
不同。
在第一种情况下,我得到了一条绿色的曲线和一条警告消息,告诉我'+=' on a read-only list creates a new list under the hood
,然后它给了我一个解决方案,把列表改为可变类型。
另一方面,第二个示例工作得很好,我一直认为这两个示例之间的差异是语法问题,而不是数据处理方式的实际差异。
有人能解释一下为什么吗
是只有Kotlin还是所有语言的工作方式都一样,只是我没有意识到这一点?
谢谢你的回答!
2条答案
按热度按时间92vpleto1#
你可能会认为
myList += "A"
和其他语言中的myList = myList + "A"
是一样的,但是只有当myList
的类型没有重载plusAssign
操作符时,在Kotlin中才是这样。一般来说,只要有可能,
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")
,myList = myList.plus("A")
调用在所有Collection
上定义的plus
。从其实现中可以看到,它创建集合的副本并返回,然后将其分配给myList
。边注:你可以使用IntelliJ中的“replace overloaded operator with function call”快速操作来检查操作符降低到什么调用。只需将插入符号放在操作符上,单击灯泡并选择操作。
g52tjvyc2#
因此,如果一个对象是不可变的,那么你不能“原地”改变它。+=原地改变一个对象,而as +返回一个新对象。在第二个例子中,你用一个由旧值构造的newlist替换mylist。