如何在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。 但是从我所了解的情况来看,每次我需要观察值时,我都必须将其转换为用户类型。