如何实例化Kotlin密封类Result?RxJava错误处理问题
问题分析与解决方案
嘿,我来帮你搞定这个问题!你没法实例化Result的核心原因是:密封类Result本身没有对外暴露的构造函数——Kotlin密封类的设计初衷就是让你通过它内部定义的子类(也就是你写的Success和Error)来创建实例,而不是直接实例化密封类本身。
你的密封类定义是没问题的,但扩展函数里的实例化方式完全错了,咱们一步步修正:
1. 修正扩展函数的实例化逻辑
把你的asResult()和asErrorResult()改成直接返回密封类的子类实例,而不是试图调用Result的构造:
fun <T> Observable<T>.retrofitResponseToResult(): Observable<Result<T>> { return this.map { it.asResult() } .onErrorReturn { if (it is HttpException || it is IOException) { return@onErrorReturn it.asErrorResult<T>() } else { throw it } } } // 修正:返回Success子类实例 fun <T> T.asResult(): Result<T> { return Result.Success(this) } // 修正:返回Error子类实例 fun <T> Throwable.asErrorResult(): Result<T> { return Result.Error(this) }
2. 正确的实例化方式
除了通过扩展函数,你也可以直接在代码里手动创建Result的实例,比如:
- 创建成功结果:
Result.Success("你的数据内容")或者Result.Success(User(id=1, name="张三")) - 创建错误结果:
Result.Error(IOException("网络连接失败"))
3. 为什么原来的写法不行?
Kotlin密封类的默认构造是private的,外部代码根本无法直接调用Result(...)来创建实例。它的子类(Success和Error)作为密封类的内部类,才能继承并被实例化——这也是密封类的核心特性之一,确保所有可能的子类都在密封类的定义范围内,方便做穷尽式的when判断。
比如你后续处理Result的时候,可以这样写(穷尽所有分支,不会有编译警告):
fun handleResult(result: Result<User>) { when(result) { is Result.Success -> showUser(result.data) is Result.Error -> showError(result.t) } }
内容的提问来源于stack exchange,提问作者Zeeshan Shabbir
相关产品推荐
相关产品推荐

