listOf Kotlin返回的对象类型

时间:2020-02-24 18:44:19

标签: kotlin

正如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

为什么这样工作?这是期望的行为吗?

2 个答案:

答案 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设计中令人遗憾的决定。在此示例中,您将控制接口的定义以及接口的所有实现,因此,出错时会更加困难。