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>

查看:102
本文介绍了Kotlin:如何使用列表演员表:未选中的演员表:kotlin.collections.List< Kotlin.Any?>到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")
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&lt; Kotlin.Any?&gt;到kotlin.colletions.List&lt; Waypoint&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆