Kotlin:如何使用列表演员表:未选中的演员表:kotlin.collections.List< Kotlin.Any?>到kotlin.colletions.List< Waypoint> [英] Kotlin: How to work with List casts: Unchecked Cast: kotlin.collections.List<Kotlin.Any?> to kotlin.colletions.List<Waypoint>
问题描述
我想编写一个函数,该函数返回List
中的每个项目,而不是第一个或最后一个项目(通过点).该函数获取通用List<*>
作为输入.仅当列表的元素类型为Waypoint
:
I want to write a function that returns every item in a List
that is not the first or the last item (a via point). The function gets a generic List<*>
as input. A result should only be returned if the elements of the list are of the type 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>
时,得到警告:
When casting the List<*>
to List<Waypoint>
, I get the warning:
未经检查的演员表:kotlin.collections.List 到kotlin.colletions.List
Unchecked Cast: kotlin.collections.List to kotlin.colletions.List
我不知道要以其他方式实现它的方法.在没有此警告的情况下实现此功能的正确方法是什么?
I can't figure out a way to implement it otherwise. What's the right way to implement this function without this warning?
推荐答案
在Kotlin中,一般情况下无法在运行时检查通用参数(例如仅检查List<T>
的项目,这只是一个特殊的大小写),因此将通用类型强制转换为具有不同通用参数的另一个类型将引发警告,除非强制转换位于
In Kotlin, there's no way to check the generic parameters at runtime in general case (like just checking the items of a List<T>
, which is only a special case), so casting a generic type to another with different generic parameters will raise a warning unless the cast lies within variance bounds.
但是有不同的解决方案:
There are different solutions, however:
-
您已经检查了类型,并且非常确定强制转换是安全的.鉴于此,您可以抑制警告,其中
@Suppress("UNCHECKED_CAST")
.
@Suppress("UNCHECKED_CAST")
val waypointList = list as? List<Waypoint> ?: return null
使用 .filterIsInstance<T>()
函数,该函数检查项目类型并返回带有所传递类型的项目的列表:
Use .filterIsInstance<T>()
function, which checks the item types and returns a list with the items of the passed type:
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 { ... }
中行),因此不会引起注意.
This will create a new list of the desired type (thus avoiding unchecked cast inside), introducing a little overhead, but in the same time it saves you from iterating through the list
and checking the types (in list.foreach { ... }
line), so it won't be noticeable.
编写一个实用程序函数,该函数检查类型并在类型正确的情况下返回相同的列表,从而将类型转换(从编译器的角度来看仍未选中)封装在其中:
Write a utility function that checks the type and returns the same list if the type is correct, thus encapsulating the cast (still unchecked from the compiler's point of view) inside it:
@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
这篇关于Kotlin:如何使用列表演员表:未选中的演员表:kotlin.collections.List< Kotlin.Any?>到kotlin.colletions.List< Waypoint>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!