Kotlin RxJava可空错误

我使用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时,该observable的任何订阅者可能会感到惊讶。

我猜这是在Kotlin和Java之间来回切换的。 但是,编译器可以看到getTestUser2的差异, getTestUser2让我觉得这是可以getTestUser2

编辑

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

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

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

从文档:

Java中的任何引用都可能为null ,这使得Kotlin对来自Java的对象的严格无效安全的要求是不切实际的。 Java声明的类型在Kotlin中被专门处理,并被称为平台类型。 这种类型的空检查是放松的,所以它们的安全保证和Java一样

T! 意思是“ T还是T?

这意味着Kotlin编译器可以将flatMap函数的返回类型视为Observable<TestUser>Observable<TestUser?> ,甚至可以将Observable<TestUser>? 。 放松部分说,“我们不想用这些不知名的类型来打扰你,你可能知道得更好”。

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


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