Kotlin 中转换变量的范围是什么?

What is the scope of casted variable in Kotlin?

当在赋值的右侧转换变量时,我惊讶地发现该变量的行为仍然与转换后的类型相同,而不是最初定义的那样。 是我做错了什么还是编译器的问题?

代码:

val hippoList = listOf<Hippo>(Hippo())
val hippoMutableList : MutableList<Hippo> = hippoList as MutableList<Hippo>
hippoList.add(Hippo())

因为 hippoList 来自 List 类型,所以它是不可变的。那么在不可变类型上尝试 运行 add 函数怎么不会导致编译错误呢?

如果你在进行转换,这意味着你比编译器更了解这个执行上下文,并且你告诉编译器这个 hippoList 是一个 MutableList,所以每次下一次使用 hippoList 编译器都已经知道这个必须是 MutableList 并允许您使用 add 方法,因为您之前将它转换为 MutableList。事实上,你会得到一个运行时错误 UnsupportedOperationException,这意味着你并没有真正了解这个执行上下文,你做错了什么。因此,不要自己使用强制转换,而是让编译器来完成它的工作。

在你的例子中,不是转换为 MutableList,而是将 hippoList 转换为 MutableList hippoList.toMutableList()

当您使用 !! 从可空类型到非空类型时,当您使用它时,当您比编译器更了解执行上下文时,也会发生同样的情况。这是一个小例子

val someNullableType: String? = null
val thisStringIsNotNull = someNullableType!!

通过使用!!在 someNullableType 上,我们告诉编译器 someNullableType 也不是 null,所以我们可以这样写(就像你告诉你的 List 也是一个 MutableList 的情况一样)

someNullableType.length

但我们会更早收到异常(在我们使用 !! 调整编译器的地方)