Kotlin RxJava 可空错误

Kotlin RxJava Nullable Bug

我 运行 在我使用 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 中,编译器将最终的 return 类型推断为 Observable<TestUser?> 并且不编译。然而,在 getTestUser 中,代码确实可以编译,而当它是 运行 时,当 TestUser 返回 null.[=17 时,该可观察对象的任何订阅者都可能会感到惊讶=]

我猜这与在 Kotlin 和 Java 之间来回切换有关。但是,编译器 可以 看到 getTestUser2 中的差异这一事实让我认为这是可以修复的。

编辑

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

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

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

来自文档:

Any reference in Java may be null, which makes Kotlin’s requirements of strict null-safety impractical for objects coming from Java. Types of Java declarations are treated specially in Kotlin and called platform types. Null-checks are relaxed for such types, so that safety guarantees for them are the same as in Java

T! means “T or T?

这意味着 Kotlin 编译器可以将 flatMap 函数的 return 类型视为 Observable<TestUser>Observable<TestUser?>,甚至 Observable<TestUser>?。放松部分说的如此之多,"we don't want to bother you with these unknown types, you probably know better".

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


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