Kotlin RxJava Nullable Bug

时间:2016-02-16 19:21:32

标签: rx-java kotlin

我在使用Kotlin和RxJava的Android应用中遇到了一个问题。它如下所示。

import rx.Observable

data class TestUser(val name: String)

fun getTestUser(): Observable<TestUser> {
    return Observable.just(TestUser("Brian")).flatMap { getUser() } // this compiles
}

fun getTestUser2(): Observable<TestUser> {
    val observable = Observable.just(TestUser("Brian")).flatMap { getUser() }
    return observable // this does not compile
}

fun getUser(): Observable<TestUser?> {
    return Observable.just(null)
}

getTestUser2中,编译器将最终返回类型推断为Observable<TestUser?>并且不进行编译。但是在getTestUser中,代码会进行编译,当它运行时,当TestUser返回null时,该可观察对象的任何订阅者都会感到惊讶。

我猜这与在Kotlin和Java之间来回传递有关。但是,编译器可以看到getTestUser2中的差异这一事实让我觉得这可以解决。

修改

这是在Kotlin 1.0,即昨天(2016年2月15日)发布的最终版本。

1 个答案:

答案 0 :(得分:10)

在Kotlin中使用flatMap函数的签名如下:

public final fun <R: Any!, T: Any!> 
    Observable<T>.flatMap(
      func: ((T) -> Observable<out R!>!)!
    ) : Observable<R!>!

来自文档:

  

Java中的任何引用都可能是null,这符合Kotlin的要求   对于来自Java的对象,严格的null安全性是不切实际的。类型   Java声明在Kotlin中被特别处理并被调用   平台类型。对于这些类型,放宽空检查,以确保安全   对它们的保证与Java相同

  

T!表示“TT?

这意味着Kotlin编译器可以将flatMap函数的返回类型视为Observable<TestUser>Observable<TestUser?>,甚至是Observable<TestUser>?。放松部分说的很多,&#34;我们不想用这些未知的类型打扰你,你可能知道的更好&#34;。

由于返回类型在getTestUser()中明确给出,因此它使用第一个。由于observable的类型未明确给出 ,因此根据Observable<TestUser?>函数将其推断为getUser()

正如@voddan评论的那样,有一个未解决的问题是:https://youtrack.jetbrains.com/issue/KT-11108