RxKotlinでスリムなRx生活

  • 40
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

RxKotlinとは、RxJavaをもっとKotlinらしく使うためのライブラリとのことです。
構成としては、基本的にRxJavaの拡張関数が詰まったものになっています。

導入

まずは、RxKotlinをプロジェクトに入れます。
最新バージョンは、0.30.1です。

build.gradle
dependencies {
    compile 'io.reactivex:rxkotlin:0.30.1'
}

できること

新しいObservable作成する際に便利な関数

空のObservableの作成

observables.kt
public fun <T> emptyObservable() : Observable<T> = Observable.empty()

新しいObservableの作成

observables.kt
public fun <T> observable(body : (s : Subscriber<in T>) -> Unit) : Observable<T> = Observable.create(body)

リストからのObservableの作成

拡張関数によって、toObservableが追加されており、配列など簡単にObservableにすることができます。

observables.kt
public fun BooleanArray.toObservable() : Observable<Boolean> = this.toList().toObservable()
public fun ByteArray.toObservable() : Observable<Byte> = this.toList().toObservable()
public fun ShortArray.toObservable() : Observable<Short> = this.toList().toObservable()
public fun IntArray.toObservable() : Observable<Int> = this.toList().toObservable()
public fun LongArray.toObservable() : Observable<Long> = this.toList().toObservable()
public fun FloatArray.toObservable() : Observable<Float> = this.toList().toObservable()
public fun DoubleArray.toObservable() : Observable<Double> = this.toList().toObservable()
public fun <T> Array<out T>.toObservable() : Observable<T> = Observable.from(this)

IteratorからのObservableの作成

observables.kt
public fun <T> Iterator<T>.toObservable() : Observable<T> = toIterable().toObservable()
public fun <T> Iterable<T>.toObservable() : Observable<T> = Observable.from(this)
public fun <T> Sequence<T>.toObservable() : Observable<T> = Observable.from(object : Iterable<T> {
    override fun iterator(): Iterator<T> = this@toObservable.iterator()
})

単発のObservableの作成

observables.kt
public fun <T> T.toSingletonObservable() : Observable<T> = Observable.just(this)
public fun <T> Throwable.toObservable() : Observable<T> = Observable.error(this)

既存の処理をシンプルに書くための関数

lift

observables.kt
public fun <T, R> Observable<T>.lift(operator : (Subscriber<in R>) -> Subscriber<T>) : Observable<R> = lift(object : Observable.Operator<R, T> {
    override fun call(t1: Subscriber<in R>?): Subscriber<in T> = operator(t1!!)
})

combineLatest

observables.kt
fun <T, R> List<Observable<T>>.combineLatest(combineFunction: (args: List<T>) -> R): Observable<R> =
        Observable.combineLatest(this, { combineFunction(it.asList() as List<T>) })

switchOnNext

observables.kt
public fun <T> Observable<Observable<T>>.switchOnNext(): Observable<T> = Observable.switchOnNext(this)

zip

observables.kt
fun <T, R> List<Observable<T>>.zip(zipFunction: (args: List<T>) -> R): Observable<R> =
        Observable.zip(this, { zipFunction(it.asList() as List<T>) })

新しく定義された便利な関数

Nullな値を返さないようにしてくれるfilterNotNull関数

observables.kt
public fun <T : Any> Observable<T?>.filterNotNull() : Observable<T> = lift { s ->
    subscriber<T?>().
            onCompleted { s.onCompleted() }.
            onError { t -> s.onError(t) }.
            onNext { v -> if (v != null) s.onNext(v) }
}

Nullな値が来た時にエラーを出したい場合はrequireNoNulls関数

observables.kt
public fun <T : Any> Observable<T?>.requireNoNulls() : Observable<T> = lift { s ->
    subscriber<T?>().
            onCompleted { s.onCompleted() }.
            onError { t -> s.onError(t) }.
            onNext { v -> if (v == null) throw NullPointerException("null element found in rx observable") else s.onNext(v) }
}

値をインデックスの値と共に受け取るにはwithIndex関数

observables.kt
public fun <T> Observable<T>.withIndex() : Observable<IndexedValue<T>> = lift { s ->
    var index = 0

    subscriber<T>().
            onNext { v -> s.onNext(IndexedValue(index++, v)) }.
            onCompleted { s.onCompleted() }.
            onError { t -> s.onError(t) }
}

おわりに

今回は、ライブラリでobservablesクラス以外は、まだ発展途中な感が強かったでobservables.ktについてだけ触れました!
まだ、バージョンは0.30.1ですが、RxJavaの拡張関数の集まりなので積極的に使っていって問題ない代物ですので、ぜひみなさんも活用してみってはいかがでしょうか。

RxKotlinのサンプルはまた後日書きたいと思います