- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想在 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/
我是一名优秀的程序员,十分优秀!