我试图在用Kotlin编写的应用程序中避免RxJava链的终端状态,所以我发现转换Observable<T>
到密封类的Observable<Result<T>>
位置Result
是正确的。
sealed class Result<T>
data class Success<T>(val data: T) : Result<T>()
data class Failure<T>(val throwable: Throwable) : Result<T>()
假设我有这个可观察到的网络请求。
fun getOrganization(): Observable<Result<Boolean>> {
return api.getOrganization("google")
.map { Success(true) }
.onErrorReturn { Failure(RuntimeException("throwable")) }
}
所以我最后要做的就是处理这样的结果。
fun main(args: Array<String>) {
getOrganization().subscribe({
when (it) {
is Success -> print("success = ${it.data}")
is Failure -> print("failure = ${it.throwable}")
}
})
}
一切都应该很好,但我在IDE中遇到此错误。
使用子类而不是基类不是很简单吗?
我发现,如果我明确地强制转换Success(true)
为Result<Boolean>
一切正常,但会显示此警告。
为什么会发生,我在做什么错呢?
UPD。似乎这里的主要问题是在rxjava的onErrorReturn运算符附近。如果我将其完全删除,那么即使没有out
答案之类的关键字,它也能正常工作。
如果我Success
从map和onErrorReturn两者返回,则out
关键字有助于摆脱错误。
但是,如果我Failure
从onErrorReturn返回,仍然会出现错误。编译器必须知道,Failure
Result
与同类型化Boolean
的Success
。我应该怎么做才能避免它或满足它的要求?
也许您误解了Kotlin中的一般差异。它Success<Boolean>
是的子类型,因此效果很好Result<Boolean>
。因此,报告了“不需要投放”警告,下面的代码可以正常工作:
val ok:Success<Boolean> = Success(true);
val result:Result<Boolean> = ok;
但是您不能将a分配给a Success<Boolean>
,Result<Any>
因为它们的类型参数不同,因此,为什么编译器会报告“ Type mismatch ”错误,例如:
val ok:Success<Boolean> = Success(true);
val result1:Result<Any> = ok;// error
val result2:Result<out Any> = ok;// ok
要修复错误和警告,您可以尝试以下代码:
fun getOrganization(): Observable<out Result<Boolean>> {
return api.getOrganization("google")
.map<Result<Boolean>> { Success(true) }
.onErrorReturn { Failure(RuntimeException("throwable")) }
}
有关更多详细信息,请参见java通用子类型和kotlin类型投影。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句