【问题标题】:Difference between myList += "A" vs myList = myList + "abc" in Kotlin?Kotlin 中 myList += \"A\" 与 myList = myList + \"abc\" 之间的区别?
【发布时间】:2023-02-24 10:25:36
【问题描述】:
我对科特林很陌生。
我正在使用 IntelliJ,IDE 告诉我这段代码 myList += "abc" 与这段代码 myList = myList + "abc" 不同。
在第一种情况下,我得到一条绿色的波浪线和一条警告消息,告诉我'+=' on a read-only list creates a new list under the hood。然后它给了我一个将列表更改为可变类型的解决方案。
另一方面,第二个例子工作得很好。我一直认为这两个示例之间的区别是语法问题,而不是数据处理方式的实际区别。
有人可以解释为什么会这样吗?
是只有 Kotlin 还是所有语言都以相同的方式工作而我只是不知道?
感谢您的回答!
【问题讨论】:
标签:
list
kotlin
collections
【解决方案1】:
所以,如果一个对象是不可变的,那么你就不能“就地”改变它。 += 就地改变一个对象,而 as + 返回一个新对象。在第二个中,您将用从旧值构建的新列表替换 mylist。
【解决方案2】:
您可能认为 myList += "A" 与 myList = myList + "A" 相同,就像在某些其他语言中一样。然而,只有当 myList 的类型没有重载 plusAssign 运算符时,这在 Kotlin 中才成立。
一般来说,只要有可能,a += b 就会降低到 a.plusAssign(b)。如果在a 上没有定义合适的plusAssign 运算符,它只会降低到a = a + b(又名a = a.plus(b))。
另请参阅文档 here。
MutableList(实际上,所有MutableCollections)确实定义了一个plusAssign,所以假设myList是一个MutableList,myList += "A"降低到myList.plusAssign("A")。 plusAssign 的implementation 只是在集合上调用add,并不创建列表的副本。
另一方面,myList = myList + "A"降低为myList = myList.plus("A"),调用plus,定义在所有Collections上。从它的implementation 可以看出,它创建了集合的副本并将其返回,然后您将其分配给myList。
旁注:您可以使用 IntelliJ 中的“用函数调用替换重载运算符”快速操作来检查运算符降低到什么调用。只需将插入符放在运算符上,单击灯泡并选择操作。