我们知道Kotlin中的List是不可变的,即你不能像下面那样添加和删除。
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
但是如果我们将其转换为ArrayList,则添加和删除工作。
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
我只是觉得这很奇怪,因为myList实际上是一个List,它假设是不可变的。并且施放它,允许它被改变。
上面做了什么(转换为Array并修改内容)是合法的,还是语言需要改进以禁止它?
答案 0 :(得分:6)
有一些不同类型的不变性:
从单独的SO回答here中提到了一个。
Readonly - 你不应该改变它(Kotlin的列表),但有些东西可能(强制转换为Mutable,或者从Java改变)。
List
只是一个没有变异方法的接口,但如果将其转换为MutableList
,则可以更改该实例。
然后有人继续评论Kotlin为了直接使用Java集合而选择只读,因此使用Java集合没有任何开销或转换。
Kotlin List是readonly,而不是一成不变的。其他调用者(例如Java)可能会更改列表。 Kotlin调用者可能会列出并更改它。没有不可改变的保护。
答案 1 :(得分:1)
合法吗?嗯,是。有些用例会有意义。
这是个好主意吗?我想不是,特别是如果你正在讨论一些由外部库返回的列表。如果有人实际上提供了一些真正不可变且不实现List
的{{1}}实现,则转换将失败。目前(Kotlin 1.0.2),Kotlin MutableList
的所有Lists
也MutableList
并不意味着每个List
你&#39;我们的代码中也会看到MutableList
。
答案 2 :(得分:1)
现在,如果您使用 listOf(),您将获得一个包含所有方法的List,这会改变列表,抛出java.lang.UnsupportedOperationException:
val list = listOf(1, 2)
val mlist = list as MutableList
mlist.add(3)
这引发:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)