Kotlin:如何使用列表类型转换:未选中类型转换:kotlin.collections.List<Kotlin.Any?>到 kotlin.colletions.List<Waypoint> [英] Kotlin: How to work with List casts: Unchecked Cast: kotlin.collections.List&lt;Kotlin.Any?&gt; to kotlin.colletions.List&lt;Waypoint&gt;

查看:98
本文介绍了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 时,我收到警告:

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,这只是一个特例),因此将泛型类型转换为具有不同泛型参数的另一个类型将引发警告,除非转换位于 方差界限.

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").

  • You have checked the type and you are quite sure that the cast is safe. Given that, you can suppress the warning with @Suppress("UNCHECKED_CAST").

@Suppress("UNCHECKED_CAST")
val waypointList = list as? List<Waypoint> ?: return null

  • 使用.filterIsInstance() 函数,它检查项目类型并返回包含传递类型的项目的列表:

  • 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屋!

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