【问题标题】:Kotlin RxJava Nullable BugKotlin RxJava 可空的错误
【发布时间】:2016-02-16 19:21:31
【问题描述】:

我在使用 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&lt;TestUser?&gt; 并且不会编译。然而,在getTestUser 中,代码确实会编译,并且当它运行时,当TestUser 返回null 时,该可观察对象的任何订阅者都可能会感到惊讶。

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

编辑

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

【问题讨论】:

标签: rx-java kotlin


【解决方案1】:

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

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! 表示“TT?

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

由于返回类型在getTestUser() 中明确给出,所以它使用第一个。由于observable 的类型没有明确给出,它根据getUser() 函数将其推断为Observable&lt;TestUser?&gt;


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

【讨论】:

  • 接受了这个。很好的研究和介绍。这就说得通了。我可能会像第二个示例一样在返回值之前分配值,从而开始变得更加明确。我想要我能得到的所有类型安全。
  • 这很奇怪。没有类型声明的赋值不应该改变任何事情。
  • 团队确认这是一个错误。问题:youtrack.jetbrains.com/issue/KT-11108
  • @voddan 有趣!
猜你喜欢
  • 2019-02-27
  • 2019-09-25
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 2018-03-21
相关资源
最近更新 更多