kotlin - is-check 或涉及类型的非泛型部分的强制转换

标签 kotlin

我在阅读 Kotlin 引用资料时遇到了几个问题:

在“类型删除和泛型类型检查”中,它提到:

当您已经静态检查了实例的类型参数时(在编译时
time),您可以进行涉及类型的非泛型部分的 is-check 或强制转换。笔记
在这种情况下省略尖括号


他们举了一个例子:

fun handleStrings(list: List<String>) {
    if (list is ArrayList) {
        // `list` is smart-cast to `ArrayList<String>`
    }
}

Q1:我测试自己
val a = mutableListOf(1, 2, 3)
val b = listOf(1, 2, 3)
println(a is List)   //error, should use List<*>
println(b is MutableList)   //can compile

我不明白为什么他们得到不同的结果。

Q2:我发现我无法使用从 List 到 ArrayList 的智能转换
println(listOf(1, 2, 3) is ArrayList)  //false
println(listOf(1, 2, 3) is MutableList)  //true

我记得,listOf() 是由 Kotlin 中的 ArrayList 实现的,它调用 asList ,它在 Arrays.java 中返回一个 ArrayList。
那么,为什么 listOf() 不能智能转换为 ArrayList?

最佳答案

A1:在第一种情况下,您从子类转换为父类(super class)。这没有任何意义,因为子类的实例总是可以用作父类(super class)的实例而无需强制转换:

val a: MutableList<Int> = mutableList(1, 2, 3)
val b: List<Int> = a

因此,Kotlin 编译器没有实现用于楼上转换的通用智能转换,而是使用需要星形投影的默认转换规则。

在第二种情况下,您从父类(super class)转换为子类,因此它按预期工作。

A2:有两种不同的ArrayList类。尝试运行此代码:

println(listOf(1, 2, 3)::class)
println(ArrayList<String>()::class)

它打印:
class java.util.Arrays$ArrayList
class java.util.ArrayList
listOf返回一个嵌套类 Arrays.ArrayList ,而不是 ArrayList你通常一起工作。

关于kotlin - is-check 或涉及类型的非泛型部分的强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59956901/

相关文章:

java - 经过 x 时间后自动从列表中删除

android - 类型 'State<List<User>?>' 没有方法 'getValue(Nothing?, KProperty<*>)',因此它不能用作委托(delegate)

Kotlin 使用 Android Studio 查找代码中的所有硬编码字符串

string - 字符串中的美元符号字符

android - 删除doOnTextChanged上的文本会删除我以编程方式设置的编辑文本的特殊格式

kotlin - 错误 : unresolved reference: roundToInt

android - Android Gradle Kotlin Dsl 中 Unresolved reference 问题

intellij-idea - 有没有办法从 kotlin 项目的 build.gradle 获取版本?

android - Google TalkBack 服务如何在按钮/文本/图像/等上绘制矩形?

kotlin - 如何将外部可调用成员函数添加到匿名对象?