如何检查泛型类型/子类型



我需要一个接收<T>列表和<T>返回列表的函数,但对<Number>列表进行一些逻辑处理

fun <T> listOfNumbers(list:List<T>):List<T>{
return if (list is List<Number>) {
list.slice(0..list.lastIndex step 2)
} else list

不能工作,因为kotlin擦除类型。

我正在尝试具体化,诸如此类

inline fun <reified T> listOfNumbers(list:List<T>):List<T> {
return when (T::class) {
Number::class -> list.slice(0..list.lastIndex step 2) as List<T>
else -> list
}
}

但是条件不起作用

主:

fun main() {
println(listOfNumbers(listOf(1, 2, 3, 4, 5)))
println(listOfNumbers(listOf("1", "2", "3", "4", "5")))
}

结果:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

期待:

[1, 3, 5]
[1, 2, 3, 4, 5]

这是因为您将List<Int>传递给您的函数,而不是List<Number>。当您没有在listOf()中指定列表的类型时,它会隐式地使用最特定的类型。这样就可以了:

println(listOfNumbers(listOf<Number>(1, 2, 3, 4, 5)))

你可以修改你的函数如下,以允许它工作在任何子类型的Number:

inline fun <reified T> listOfNumbers(list:List<T>):List<T> {
return when {
T::class.isSubclassOf(Number::class) -> list.slice(0..list.lastIndex step 2)
else -> list
}
}

如果您在JVM上,上面的代码需要Kotlin反射库。或者,您可以使用Java反射,将T::class.isSubclassOf(Number::class)替换为Number::class.java.isAssignableFrom(T::class.java)

最新更新