我在使用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)
}

In getTestUser2, the compiler infers the final return type as Observable<TestUser?> and doesn't compile. However in getTestUser the code does compile, and when it's run, any subscriber to that observable may be in for a surprise when the TestUser comes back null.

I'm guessing it's something to do with going back and forth between Kotlin and Java. But, the fact that the compiler can see the difference in getTestUser2 makes me think this could be fixable.

编辑

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

推荐答案

The signature of the flatMap function is as follows when used in Kotlin:

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

从文档中:

Java中的任何引用都可能是null,这使得Kotlin的需求

and

T! means “T or T?

This means that the Kotlin compiler can regard the return type of the flatMap function as either Observable<TestUser> or Observable<TestUser?>, or even Observable<TestUser>?. The relaxation part says so much as, "we don't want to bother you with these unknown types, you probably know better".

Since the return type is explicitly given in getTestUser(), it uses the first. Since the type of observable is not explicitly given, it infers it to Observable<TestUser?>, based on the getUser() function.


As @voddan commented, there is an open issue discussing this problem: https://youtrack.jetbrains.com/issue/KT-11108

Kotlin相关问答推荐

在Kotlin中将String转换为T

某些公共函数显然不能在类实例上访问;Klaxon示例

Kotlin:有限的并行性并不是限制并行性

多模块Kotlin项目中的FreeFair

ActivityResultContracts TakePicture 结果总是返回 false

在 Kotlin 中,如何绑定扩展方法以在接收器范围函数中工作

具有泛型类型的 Kotlin 密封接口不会为其子类型推断约束

我们应该在 Effect 和 Either 之间 Select 哪个作为我们业务服务的返回类型?

奇怪的 cotlin check Not Null 参数错误

SpringBoot 2.5.0 对于 Jackson Kotlin 类的支持,请在类路径中添加com.fasterxml.jackson.module: jackson-module-kotlin

无法为 retrofit2.Call 调用无参数构造函数

在kotlin中,如何模拟封装回调函数?

如何在 Jetpack Compose 的 LazyColumn/LazyRow 中禁用和启用滚动?

我们如何在Java注释声明中引用Kotlin常量?

Mocked suspend函数在Mockito中返回null

如何限制kotlin协程的最大并发性

uses-sdk:minSdkVersion 16 不能小于库中声明的版本 23

如何在Kotlin中将字符串转换为InputStream?

访问Kotlin中的属性委托

Kotlin中的嵌套let块