gpt4 book ai didi

generics - 具有依赖于接收器类型参数的泛型类型的 Kotlin 扩展函数(未明确指定)

转载 作者:行者123 更新时间:2023-12-02 12:47:11 24 4
gpt4 key购买 nike

有时我想在泛型类型上有一个扩展函数,其参数或返回值是给定类型参数的子类型,但不必指定实际类型参数。 (也许,如果不清楚,代码会更好地阐明它?)

使用 this answer 的签名:

inline fun <reified U : T, T> Iterable<T>.partitionByType(): Pair<List<U>, List<T>>

它迫使我按如下方式使用它:
val list : List<SomeType>
list.partitionByType<InterestedType, SomeType>()

但是,我更想写的是以下内容:
list.partitionByType<InterestedType>()

哪里 InterestedType是列表的类型参数的子类型,即 SomeType .上面的两个解决方案都应该给我 Pair<List<InterestedType>, List<SomeType>>作为返回值。

然而,这实际上是不可能的。我想到的最好的是类似于以下的签名:
 inline fun <reified U : Any> Iterable<Any>.partitionByType(): Pair<List<U>, List<Any>>

但随后我们丢失了实际类型 T/ SomeType这是众所周知的。调用方仍然可以进行未经检查的强制转换,但这不是我所追求的。

所以我的问题是:这有可能吗?有类似 U : T 的东西到位,没有指定 T ?或者在这方面有什么计划(KEEP 或 Kotlin 问题可用)?

对我来说,这听起来像是一个合理的功能,至少只要它仅应用于扩展功能。如果不是,那么我目前可能只是忽略/忽略的问题是什么?
我并不是真正要寻找的是一种解决方法(例如具有中间类型),但将其作为答案也可能是值得的。

我想得越多。如果泛型类型的扩展函数声明如下,不是更正确吗?
fun SomeType<T>.extended()

代替
fun <T> SomeType<T>.extended()

因为:如果我在 SomeType<T>的控制之下并且会在那里添加该函数,我不需要任何通用类型信息来声明它,例如那么以下就足够了:
fun extended()

具有自己的泛型类型的函数也是如此,例如:
fun <U : T> extended2()

现在将其添加为扩展函数会强制添加 T -generic 类型,虽然我们想应用它的类型,显然是 SomeType<T> :
fun <T, U: T> SomeType<T>.extended2()

最佳答案

另一个不太优雅的解决方案,可能被认为比传递 type<T>() 更糟糕因为它不是通用的,并且每个这样的函数都需要样板,所以返回一个包装对象(这同样毫无意义)。

但是,随着使用 inline类,它可以在没有任何运行时开销的情况下实现,所以无论如何我都会在这里发布:

fun main() {
println(listOf<Number>(1, 2.0, 3f).doPartition.byType<Int>())
}

inline class PartitionByTypeWrapper<T>(val list: List<T>) {
inline fun <reified U : T> byType(): Pair<List<U>, List<T>> {
val (us, ts) = list.partition { it is U }
@Suppress("UNCHECKED_CAST")
return us as List<U> to ts
}
}

inline val <T> List<T>.doPartition get() = PartitionByTypeWrapper(this)

关于generics - 具有依赖于接收器类型参数的泛型类型的 Kotlin 扩展函数(未明确指定),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56327840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com