我想编写一个函数,返回List
中不是第一个或最后一个项目(via点)的每个项目。该函数得到一个通用的列表
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}
}
铸造列表时
未选中的演员:kotlin.集合.列表到kotlin.同事.列表
否则我想不出实现它的方法。没有这个警告,实现这个功能的正确方法是什么?
在静态编程语言中,在一般情况下,没有办法在运行时检查泛型参数(比如只检查List的项目)
然而,有不同的解决方案:
>
您已经检查了类型,并且非常确定强制转换是安全的。鉴于此,您可以使用@Suppress("UNCHECKED_CAST")
取消警告。
@Suppress("UNCHECKED_CAST")
val waypointList = list as? List<Waypoint> ?: return null
使用. filterIsInstance
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
为了改进@hotkey的答案,我的解决方案如下:
val waypointList = list.filterIsInstance<Waypoint>().takeIf { it.size == list.size }
这为您提供列表
对于泛型类,无法检查强制转换,因为类型信息在运行时被删除。但是您可以检查列表中的所有对象都是Waypoint
,因此您可以使用@Suppress("UNCHECKED_CAST")
来抑制警告。
为避免此类警告,您必须传递可转换为Waypoint
的对象的List
。当您使用*
但尝试将此列表作为类型化列表访问时,您将始终需要强制转换,并且此强制转换将被取消选中。