gpt4 book ai didi

java - Kotlin:泛型和方差

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:03:04 25 4
gpt4 key购买 nike

我想在 Throwable 上创建一个扩展函数那,给定一个 KClass ,递归地搜索与参数匹配的根本原因。以下是一种可行的尝试:

fun <T : Throwable> Throwable.getCauseIfAssignableFrom(e: KClass<T>): Throwable? = when {
this::class.java.isAssignableFrom(e.java) -> this
nonNull(this.cause) -> this.cause?.getCauseIfAssignableFrom(e)
else -> null
}

这也行:

fun Throwable.getCauseIfAssignableFrom(e: KClass<out Throwable>): Throwable? = when {
this::class.java.isAssignableFrom(e.java) -> this
nonNull(this.cause) -> this.cause?.getCauseIfAssignableFrom(e)
else -> null
}

我这样调用函数:e.getCauseIfAssignableFrom(NoRemoteRepositoryException::class) .

然而,Kotlin docs关于泛型说:

This is called declaration-site variance: we can annotate the type parameter T of Source to make sure that it is only returned (produced) from members of Source, and never consumed. To do this we provide the out modifier

abstract class Source<out T> {
abstract fun nextT(): T
}

fun demo(strs: Source<String>) {
val objects: Source<Any> = strs // This is OK, since T is an out-parameter
// ...
}

在我的例子中,参数 e不返回,但消耗。在我看来,它应该声明为 e: KClass<in Throwable>但这不编译。但是,如果我想到 out作为“您只能读取或返回它”和in因为“您只能为其编写或分配一个值”,所以这是有道理的。谁能解释一下?

最佳答案

其他答案已经解决了为什么您不需要在此使用网站上的差异。

仅供引用,如果您将返回值转换为预期类型,API 会更有用,

@Suppress("UNCHECKED_CAST")
fun <T : Any> Throwable.getCauseIfInstance(e: KClass<T>): T? = when {
e.java.isAssignableFrom(javaClass) -> this as T
else -> cause?.getCauseIfInstance(e)
}

但使用具体化类型更像 Kotlin。

inline fun <reified T : Any> Throwable.getCauseIfInstance(): T? =
generateSequence(this) { it.cause }.filterIsInstance<T>().firstOrNull()

这实际上与编写显式循环相同,但更短。

inline fun <reified T : Any> Throwable.getCauseIfInstance(): T? {
var current = this
while (true) {
when (current) {
is T -> return current
else -> current = current.cause ?: return null
}
}
}

并且与原始方法不同,此方法不需要kotlin-reflect

(我还将行为从 isAssignableFrom 更改为 is (instanceof);我很难想象原来的行为如何很有用。)

关于java - Kotlin:泛型和方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45579660/

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