我想写一个函数来返回 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/