我在(Rx)Java中有这个代码:
Observable.fromArray(1, 2, 3)
.flatMap(this::intToBooleanObservable, Pair::new)
.....
Run Code Online (Sandbox Code Playgroud)
我希望相应的Kotlin代码看起来像:
Observable.fromArray(1, 2, 3)
.flatMap(::intToBooleanObservable, ::Pair)
.....
Run Code Online (Sandbox Code Playgroud)
但是编译器无法推断出Pair的泛型类型,所以我现在能做的最好的事情是:
.flatMap(::intToBooleanObservable, { a, b -> a to b })
Run Code Online (Sandbox Code Playgroud)
这并不像我希望的那样简洁.
有没有办法实现这个不声明变量a和b?
这里同样的麻烦。其他一些解决方法(按照我使用的顺序),您可能会喜欢其中之一。
1)编写自己的运算符:
fun <T, U> Single<T>.flatMapPair(func: (T) -> Single<U>) : Single<Pair<T, U>> {
return this.flatMap { t -> func.invoke(t).map { u -> t to u } }
}
Run Code Online (Sandbox Code Playgroud)
2) 将包装移至条件 Observable(此处为 intToBooleanObservable),以 Pair 或更明确的自定义类型返回结果(具有 2 个子级的密封类,如 Success 和 Failure)。这使得代码更加明确:
when(it) {
is Success -> ...
is Failure -> ...
}
Run Code Online (Sandbox Code Playgroud)
3)根据 intToBooleanObservable 结果,你现在有 2 个不同的场景(我想)。通常,这是一种失败/否认,可以快速解决。对于这个问题,编写一个具有副作用的过滤器,其中谓词是一个 Observable,从而避免了这个问题:
fun <T> Observable<T>.filterSingle(predicate: (T) -> Single<Boolean>, rejectionFunction: (T) -> Unit): Observable<T> = ... //filter with the given predicate, and call rejectionFunction if item doesn't pass
Run Code Online (Sandbox Code Playgroud)
4)最后一个方法仅适用于布尔结果。如果我对未能/拒绝提供有意义的信息背后的原因感兴趣怎么办?为了代码的同质性,我放弃了这个运算符。受其他函数式语言的启发,我定义了 Either 类型并定义了泛型 Either+RxJava 运算符;mapRight、flatMapRight 以及更重要的 dropLeft。dropLeft 就像 filterSingle 的泛化。
inline fun <L, R> Observable<Either<L, R>>.dropLeft(crossinline sideEffect: (L) -> Unit): Observable<R> = this.lift { downObserver ->
object: Observer<Either<L, R>> {
override fun onError(throwable: Throwable?) = downObserver.onError(throwable)
override fun onSubscribe(disposable: Disposable?) = downObserver.onSubscribe(disposable)
override fun onComplete() = downObserver.onComplete()
override fun onNext(either: Either<L, R>) = when (either) {
is Right -> downObserver.onNext(either.value)
is Left -> sideEffect(either.value)
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望它能有所帮助。
| 归档时间: |
|
| 查看次数: |
408 次 |
| 最近记录: |