为什么不同类型的可变列表放在可变列表中时表现得像不可变的
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()
)而无需强制转换。
我们知道,在 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()
)而无需强制转换。