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
我 运行 在我使用 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
orT?
”
这意味着 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