jay*_*917 3 android kotlin rx-java
我遇到一个问题,以下代码无法在 kotlin 中编译。
// StateModel.kt
sealed class StateModel
class Loading : StateModel()
data class Success<T: Any>(val data: T) : StateModel()
data class MyError(val message: String) : StateModel()
// StateModelTransformer.kt
class StateModelTransformer<T: Any> : FlowableTransformer<T, StateModel> {
override fun apply(upstream: Flowable<T>): Publisher<StateModel> {
return upstream
.map { data -> Success(data) }
.onErrorReturn { error ->
MyError(error.message) // compile error, Type mismatch, Require Success<T>, Found MyError
}
.startWith(Loading()) // compile error, none of the following function can be called with the arguments supplied
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道为什么onErrorReturn
说需要Success<T>
类型而不是StateModel
类型。
谢谢
以下是相关声明Flowable
,供参考。让我们忽略onErrorReturn
;这与这里的问题无关。
public Flowable<T> {
public <R> Flowable<R> map(Function<? super T, ? extends R> mapper);
public Flowable<T> startWith(T value);
}
Run Code Online (Sandbox Code Playgroud)
这些是 Kotlin 推断的类型。
val upstream: Flowable<T>
val mapper: (T) -> Success<T> = { data -> Success(data) }
val map: ((T) -> Success<T>) -> Flowable<Success<T>>
= upstream::map
val mapped: Flowable<Success<T>> = map(mapper)
val loading: Loading = Loading()
val startWith:
(Success<T>) -> Flowable<Success<T>>
= mapped::startWith
startWith(loading) // type mismatch
Run Code Online (Sandbox Code Playgroud)
更具体的Success<T>
类型已经在前面推断出来了,Kotlin 不会回溯来寻找更通用的StateModel
类型。要强制发生这种情况,您可以手动声明类型,例如
// be explicit about the general type of the mapper
upstream.map { data -> Success(data) as StateModel }.startWith(Loading())
// be explicit about the generic type R = StateModel
upstream.map<StateModel> { data -> Success(data) }.startWith(Loading())
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你目前正在<T>
失败StateModel
。我建议更改基类以包含类型参数。
sealed class StateModel<out T: Any>
object Loading : StateModel<Nothing>()
data class Success<T: Any>(val data: T) : StateModel<T>()
data class MyError(val message: String) : StateModel<Nothing>()
Run Code Online (Sandbox Code Playgroud)
例如,这可以让你写:
val <T: Any> StateModel<T>.data: T?
get() = when (this) {
is Success -> data
else -> null
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4708 次 |
最近记录: |