如果使用“+”运算符添加列表,为啥 Kotlin 会将 List<List<Int>> 类型的列表更改为 List<Any>?

Posted

技术标签:

【中文标题】如果使用“+”运算符添加列表,为啥 Kotlin 会将 List<List<Int>> 类型的列表更改为 List<Any>?【英文标题】:Why does Kotlin change a list of type List<List<Int>> to List<Any> if a list is added with the "+" operator?如果使用“+”运算符添加列表,为什么 Kotlin 会将 List<List<Int>> 类型的列表更改为 List<Any>? 【发布时间】:2022-01-24 01:09:15 【问题描述】:

给定以下两个列表

val listA = listOf<List<Int>>()
val listB = listOf(1, 2, 3)

以及下面的操作

val listC = listA + listB

我正在将List&lt;Int&gt; 类型的列表添加到List&lt;List&lt;Int&gt;&gt; 类型的列表中。但是,我的 IDE 告诉我结果列表 C 的类型是List&lt;Any&gt;,而不是我预期的List&lt;List&lt;Int&gt;&gt;。谁能给我解释一下为什么?

【问题讨论】:

【参考方案1】:

查看kotlin.collections 中所有plus 运算符中的list,你会发现你调用的那个会解析为这个:

operator fun <T> Collection<T>.plus(
    elements: Iterable<T>
): List<T>

编译器非常努力地推断T 的类型,以便调用有效,并找到Any 作为这样的类型。毕竟,List&lt;List&lt;Int&gt;&gt;Collection&lt;Any&gt;List&lt;Int&gt; 也是 Iterable&lt;Any&gt;

注意还有:

operator fun <T> Collection<T>.plus(element: T): List<T>

但是,重载决议不会选择这个,因为采用Iterable&lt;T&gt; 的那个被认为是“更具体”。毕竟,它具体需要一个Iterable,而不是任何类型(T),包括Iterable。另请参阅rationale section of the spec。

你应该改用plusElement

【讨论】:

感谢您的详细解释!

以上是关于如果使用“+”运算符添加列表,为啥 Kotlin 会将 List<List<Int>> 类型的列表更改为 List<Any>?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin集合操作 ② ( MutableList 可变列表集合 | 修改 MutableList 集合的 mutator 函数 )

Kotlin集合操作 ② ( MutableList 可变列表集合 | 修改 MutableList 集合的 mutator 函数 )

为啥 Kotlin 不支持“三元运算符”[关闭]

为啥在使用 kotlin 将数据添加到 firebase 实时数据库时会得到重复值?

为啥 Kotlin 插件为 Android 项目添加 kotlin-stdlib-jre7(不是 kotlin-stdlib)参考

为啥我不能在初始化列表中使用箭头运算符?