list - Kotlin:如何使用列表强制转换:未经检查的强制转换:kotlin.collections.List<Kotlin.Any?> 到 kotlin.colletions.List<Waypoint>

标签 list generics casting kotlin

我想写一个函数来返回 List 中的每一项。那不是第一个或最后一个项目(通过点)。该函数得到一个通用的 List<*>作为输入。仅当列表元素的类型为 Waypoint 时才应返回结果:

fun getViaPoints(list: List<*>): List<Waypoint>? {

    list.forEach { if(it !is Waypoint ) return null }

    val waypointList = list as? List<Waypoint> ?: return null

    return waypointList.filter{ waypointList.indexOf(it) != 0 && waypointList.indexOf(it) != waypointList.lastIndex}
}

在施放 List<*> 时至List<Waypoint> ,我收到警告:

Unchecked Cast: kotlin.collections.List to kotlin.colletions.List

我想不出其他方法来实现它。在没有此警告的情况下实现此功能的正确方法是什么?

最佳答案

在 Kotlin 中,在一般情况下无法在运行时检查泛型参数(例如仅检查 List<T> 的项目,这只是一种特殊情况),因此将泛型类型转换为具有不同泛型参数的另一个除非类型转换位于 variance bounds 范围内,否则将发出警告.

但是有不同的解决方案:

  • 你已经检查了类型并且你很确定这个 Actor 是安全的。鉴于此,您可以 suppress the warning@Suppress("UNCHECKED_CAST") .

    @Suppress("UNCHECKED_CAST")
    val waypointList = list as? List<Waypoint> ?: return null
    
  • 使用 .filterIsInstance<T>() 函数,它检查项目类型并返回一个包含所传递类型项目的列表:

    val waypointList: List<Waypoint> = list.filterIsInstance<Waypoint>()
    
    if (waypointList.size != list.size)
        return null
    

    或在一个语句中相同:

    val waypointList = list.filterIsInstance<Waypoint>()
        .apply { if (size != list.size) return null }
    

    这将创建一个所需类型的新列表(从而避免在内部进行未经检查的强制转换),引入一点开销,但同时它使您免于遍历 list并检查类型(在 list.foreach { ... } 行中),因此不会引起注意。

  • 编写一个实用函数来检查类型并在类型正确时返回相同的列表,从而在其中封装强制转换(从编译器的角度来看仍然未经检查):

    @Suppress("UNCHECKED_CAST")
    inline fun <reified T : Any> List<*>.checkItemsAre() =
            if (all { it is T })
                this as List<T>
            else null
    

    配合用法:

    val waypointList = list.checkItemsAre<Waypoint>() ?: return null
    

关于list - Kotlin:如何使用列表强制转换:未经检查的强制转换:kotlin.collections.List<Kotlin.Any?> 到 kotlin.colletions.List<Waypoint>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36569421/

相关文章:

python - 将列表元素添加到字典值

c# 泛型重载方法分派(dispatch)不明确

javascript - 使用 + 作为转换机制是如何工作的?

Java 泛型 : Cannot convert from Object to T

c# - List<image> 异常 "Parameter is not valid."

Java ArrayList clear() 函数

python - 查找与条件匹配的第一个序列项

c# - 有没有办法编写一个通用方法,无论嵌套级别如何,都将从另一个对象返回类型为 T 的所有对象?

TypeScript 如何为泛型函数创建泛型类型别名?

c - 需要一些关于在 C 中类型转换的澄清