Kotlin:通过转换修改(不可变的)列表,这是否合法?
我们知道Kotlin中的列表是不可变的,也就是说你不能像下面那样添加和删除。
class TempClass { var myList: List? = null fun doSomething() { myList = ArrayList() myList!!.add(10) myList!!.remove(10) } }
但是如果我们像下面那样将它转换为ArrayList,则添加和删除工作。
class TempClass { var myList: List? = null fun doSomething() { myList = ArrayList() (myList!! as ArrayList).add(10) (myList!! as ArrayList).remove(10) } }
我只是觉得这很奇怪,因为myList实际上是一个List,它被认为是不可变的。 并铸造它,让它被改变。
上面做了什么(铸造到数组并修改内容)是合法的,还是语言需要改进来禁止呢?
有几种不可变性的不同types:
一个是在这里单独提到的答案。
只读 – 你不应该改变它(Kotlin的列表),但可能(转换为可变,或从Java更改)。
List
只是一个没有mutating方法的接口,但是如果你把它转换成MutableList
,你可以改变这个实例。
然后有人发表评论说,Kotlin选择只读,以便直接使用Java集合,所以在使用Java集合时没有开销或转换。
Kotlin List是只读的,不是一成不变的。 其他调用者(例如Java)可能会更改列表。 Kotlin调用者可能会列表并更改它。 没有不可变的保护。
原始来源: Kotlin和不可变的collections?
这是合法吗? 嗯,是。 有一些用例可能是合理的。
这是个好主意吗? 我认为不是,特别是如果你正在谈论铸造一个外部图书馆返回的清单。 如果有人真的交给你一些实际上是不可变的List
实现,并且不实现MutableList
,那么投射将失败。 目前(Kotlin 1.0.2),所有Kotlin的Lists
也是MutableList
,并不意味着你在代码中看到的每个List
也是一个MutableList
。
现在,如果你使用listOf(),你会得到一个列表与所有的方法,这个列表变异,抛出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)