正如Kotlin文档所说的listOf<T>
有三种实现:无参数,一个参数和varargs。每个函数应返回不可变的List<T>
。
val emptyList = listOf<String>()
val oneArgList = listOf("asd")
val varargsList = listOf("asd", "asd")
if (emptyList is MutableList) println("emptyList is mutable")
if (oneArgList is MutableList) println("oneArgList is mutable")
if (varargsList is MutableList) println("varargList is mutable")
执行上面的代码会导致
oneArgList is mutable
varargList is mutable
为什么这样工作?这是期望的行为吗?
答案 0 :(得分:4)
为什么这样工作?
如果您签出源代码,就会发现它实际上创建了Java ArrayList
。这利用了JDK,而不必在Kotlin中实现ArrayList
。请注意,由于MutableList
函数已经指定它是listOf()
而不是List
,因此即使转换成功,对MutableList
的转换也是不好的。
emptyList()
(或listOf()
)使用在Kotlin中实现的EmptyList
单例,它是真正不变的。
这是理想的行为吗?
实际上没有。但是,它确实可以提供一个不可变的接口。只要支持接口结构符合接口数据结构的确切实现方式,这实际上并不重要。作为程序员,您还应该在使用合同时遵守合同。
答案 1 :(得分:1)
您说“每个人都应该返回不可变列表”,但是如果您查看这三个函数的文档,第一个函数会返回一个不可变列表,而后两个说它们返回一个只读列表。只读列表不一定是不变的。
List接口不能保证不变性。它仅将自己描述为仅提供只读方法。
在实际操作中,随意进行is
检查是很长的时间代码味道。有一些合理的狭窄用例。就像Google的recommended way to create a DialogFragment and communicate back to the Activity一样,但是(IMO)这样的东西是一种黑客,可以绕过原始的Activity and Fragments设计中令人遗憾的决定。在此示例中,您将控制接口的定义以及接口的所有实现,因此,出错时会更加困难。