【问题标题】:Kotlin: Unchecked cast in my generic functionKotlin:我的通用函数中未经检查的强制转换
【发布时间】:2020-05-30 13:26:03
【问题描述】:

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

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"
}

我可以这样写:

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
    }
}

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

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

谢谢。

【问题讨论】:

  • 你能描述一下你的函数应该做什么吗?
  • @IR42 我想如果我理解得很好,他想在 lambda 返回非空值时返回一个不可为空的字符串,在 lambda 返回可空值时返回一个可空字符串。
  • Tenfour04 的回答是正确的,你可以阅读这篇解释 Generic 的边界如何工作的文章:proandroiddev.com/…

标签: generics kotlin casting


【解决方案1】:

编译器不够复杂,无法看出K 唯一可能的类型是StringString?(因为String 是最终的),所以对于编译器来说,K 可能是其他一些子类型String? ,所以转换你的文字 String 可能是不安全的。并且由于K 是一个泛型类型,由于类型擦除,强制转换是未检查的。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2019-09-13
    相关资源
    最近更新 更多