Kotlin:我的通用函数中未经检查的强制转换

hog*_*oge 4 generics casting kotlin

我正在尝试使用泛型将我的两个函数合并为一个。

fun <T> List<T>.toElementOrSize1(keySelector: (T) -> String): String {
    val key = keySelector(first())
    return if (all { keySelector(it) == key }) key else "size = $size"
}

fun <T> List<T>.toElementOrSize2(keySelector: (T) -> String?): String? {
    val key = keySelector(first())
    return if (all { keySelector(it) == key }) key else "size = $size"
}
Run Code Online (Sandbox Code Playgroud)

我可以这样写:

fun <T, K : String?> List<T>.toElementOrSize(keySelector: (T) -> K): K {
    val key = keySelector(first())
    return if (all { keySelector(it) == key }) {
        key
    } else {
        "size = $size" as K
    }
}
Run Code Online (Sandbox Code Playgroud)

这可行,但我收到了未经检查的演员警告。

为什么发出此警告?以及如何避免这个警告?

谢谢。

Ten*_*r04 8

编译器不够复杂,无法看到K和 的String唯一可能类型String?(因为String是最终类型),因此对于编译器来说, K 可能是 的其他子类型String?,因此转换您的文字String可能是不安全的。由于K是泛型类型,因此由于类型擦除而不会检查转换。

使用泛型时会出现很多类似的情况。这并不意味着您一定做错了什么,只是编译器没有足够的知识来确定您没有做错。您可以@Suppress("UNCHECKED_CAST")在函数或语句之前使用来删除警告并确认您知道这是安全的强制转换。这并不意味着您正在做一些古怪或设计不当的事情。它在标准库源代码中多次使用。