簡體   English   中英

Kotlin構造函數引用泛型

[英]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 })

這並不像我希望的那樣簡潔。

有沒有辦法在不聲明變量ab情況下實現這一點?

同樣麻煩在這里。 其他一些解決方法(按照我使用它們的順序),您可能會喜歡其中一種。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM