[英]Kotlin constructor reference with generics
我在(Rx)Java中有這個代碼:
Observable.fromArray(1, 2, 3)
.flatMap(this::intToBooleanObservable, Pair::new)
.....
我希望相應的Kotlin代碼看起來像:
Observable.fromArray(1, 2, 3)
.flatMap(::intToBooleanObservable, ::Pair)
.....
但是編譯器無法推斷出Pair的泛型類型,所以我現在能做的最好的事情是:
.flatMap(::intToBooleanObservable, { a, b -> a to b })
這並不像我希望的那樣簡潔。
有沒有辦法在不聲明變量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 } }
}
2)將包裝移動到條件Observable(此處為intToBooleanObservable),將結果作為Pair或更明確的自定義類型返回(帶有2個子項的密封類,如Success和Failure)。 這樣可以實現更明確的代碼
when(it) {
is Success -> ...
is Failure -> ...
}
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
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)
}
}
}
希望它可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.