如何在RxJava 2和Kotlin中将null传递给可空类型的Observable

我像这样初始化我的变量:

val user: BehaviorSubject<User?> user = BehaviorSubject.create() 

但我不能这样做。 IDE会引发错误: –

 user.onNext(null) 

这样做,IDE说你永远不会是空的: –

 user.filter( u -> u!=null) 

正如Guenhter所解释的,这是不可能的。 然而,我不建议null对象模式,我建议一个Optional类型的实现:

 data class Optional<T>(val value: T?) fun <T> T?.asOptional() = Optional(this) 

这使你的意图更清晰,你可以在你的函数中使用解构声明:

 Observable.just(Optional("Test")) .map { (text: String?) -> text?.substring(1)?.asOptional() } .subscribe() 

在这里使用空对象模式会导致比解决更多的错误。

如果你使用rxkotlin / rxjava 2.0(我认为是这样)比答案是:你不能。 原因在这里解释。

这是界面的一个突破。 看看Observable接口

 public interface Observer<T> { /** ... */ void onSubscribe(@NonNull Disposable d); /** ... */ void onNext(@NonNull T t); /** ... */ void onError(@NonNull Throwable e); /** ... */ void onSubscribe(@NonNull Disposable d); /** ... */ void onNext(@NonNull T t); /** ... */ void onError(@NonNull Throwable e); ... 

@NonNull将被Kotlin编译器考虑,因此你不能传递null。

即使你可以, onNext会立即抛出一个错误:

 @Override public void onNext(T t) { if (t == null) { onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources.")); return; } ... } 

如果你真的需要这样的东西,你必须伪造它。 例如通过创建一个表示你的null元素的User的静态对象。

例如

 data class User(val username, val password) { companion object { val NULL_USER = User("", "") } } ... val user = BehaviorSubject.create<User>() ... user.onNext(User.NULL_USER) ... user.filter { it !== User.NULL_USER } 

但是,这是可能的,尽量避免null概念,也许想想另一个解决方案,这是不需要的。

非常感谢你所有的答案,但我最终用这个解决方案:

class UserEnvelope(private val:User?){}

并使用BehaviorSubject

这最适合我的要求。

现在关于可选项,我不知道,但我不认为我可以得到类型为用户,我必须输入每次我需要访问它。 我错了吗? 我是Kotlin新手。

非常感谢你所有的答案,但我最终用这个解决方案:

class UserEnvelope(val user:User?){}

在观察者中使用这个。

这最适合我的要求。

我是Kotlin新手,所以我不知道如何使用Optionals。 但是从我所了解的情况来看,每次我需要观察值时,我都必须将其转换为用户类型。