为什么不同类型的可变列表放在可变列表中时表现得像不可变的

Why mutable lists of different types behave as immutable when put inside a mutable list

我们知道,在 Kotlin 中可以创建不同类型的可变列表的可变列表,例如:

val list = mutableListOf(
            MutableList<Int>(3) { 0 }, 
            MutableList<String>(2) { "aaa" }
        )  

并且可以(如预期的那样)更改主列表,例如:

list.add(MutableList<Double>(4) { 0.0 }

经过此操作后,println(list)的结果如下:

[[0, 0, 0], [aaa, aaa], [0.0, 0.0, 0.0, 0.0]]

但不可能更改子列表,
例如操作:

list[0][1] = 2
list[1].add("bbb")

产生错误信息:
整型文字不符合预期类型 Nothing

类型不匹配:推断类型为字符串,但没有预期的类型
分别...

我的问题是:
为什么这些嵌套的子列表——声明为可变的——表现得像它们不可变的一样???
有没有办法改变这些嵌套的子列表???


顺便...
我已经检查过,声明为可变的嵌套子列表在它们都是相同类型时表现得非常正常。
有可能 - 正如预期的那样 - 在这种情况下更改那些嵌套的子列表...

由于 MutableList 是类型化的,因​​此在向其添加项目之前,您必须让编译器知道子列表的确切类型。 以下代码:

(list[0] as MutableList<Int>)[1] = 2
(list[1] as MutableList<String>).add("bbb")

效果很好。但是,当您尝试转换为错误的 MutableList 类型时,在运行时仍然会遇到问题,这就是报告警告(“未经检查的转换”)的原因。

当所有子列表 类型相同时 例如Int 顶级 list 类型被编译器明确推断为 MutableList<MutableList<Int>> 因此您不必明确告诉编译器子列表的类型,因为它已经知道它们。但是当子列表是不同类型时,编译器将 list 的类型推断为 MutableList<MutableList<Any>> 并限制您仅调用 MutableList 的非类型化方法(例如 clear())而无需强制转换。