如果提供为RxJava Observable,则必须将Kotlin密封类子类强制转换为基类

Pavelkorolevxyz

我试图在用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答案之类的关键字,它也能正常工作

没有onErrorReturn

如果我Success从map和onErrorReturn两者返回,则out关键字有助于摆脱错误。

但是,如果我Failure从onErrorReturn返回,仍然会出现错误。编译器必须知道,Failure Result与同类型化BooleanSuccess我应该怎么做才能避免它或满足它的要求?

失败

holi-java

也许您误解了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类型投影

java泛型子类型

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如果必须将以下JSON转换为Java Object,DTO类应如何显示?

如果子类对象被强制转换为超类会发生什么

将对象定义为通用密封类的子类型?

如何将密封的Kotlin类转换为Java类

Logback提供错误无法将类为'java.lang.String'的对象'3 gb'强制转换为类'ch.qos.logback.core.util.FileSize'

即使提供了强制转换类后,ClassCastException

Kotlin:使用不同的子类多次实现通用接口(基类为约束)

如何将 kotlin 中的密封类转换为 Java

是否在Java中强制执行了密封类,如果是,则如何?

如果将一个类声明为final,则必须将这些方法声明为final

使用密封类或与Moshi的接口时,无法为类创建转换器

将 Retrofit RxJava Result 映射为密封类成功和失败

如何阅读 Kotlin 中的密封类子类?

Kotlin域类转换为子类

将类转换为Kotlin的子类

如果类没有为该方法提供实现,为什么类对象可以调用toString方法?

为什么必须将在A类中声明为好友的函数在B类中定义为公共函数?

Java:阻止子类提供与基类不同的接口

将超类的对象强制转换为子类-向下转换

如果将基类的可选功能存储在辅助类中,则辅助类是否应将子类作为基类?

RxJava 可观察为类字段

如果我在c ++中将(指向类A的指针)转换为(指向其子类B的指针)会发生什么

强制密封类

如果没有为强制选项提供任何参数,则zparseopts将下一个选项作为参数

如何在Spring中为自动装配提供基类?

无法将类强制转换为其子类?

从通用父类返回“ this”需要强制转换为子类

如何将基类的实例设置为子类的属性?

Xgboost-如果整数仅为0和1,我们是否必须将整数转换为因数