如何传递null可观察到的可空类型RxJava 2和科特林
问题描述:
我初始化我的变量是这样的: -如何传递null可观察到的可空类型RxJava 2和科特林
val user: BehaviorSubject<User?> user = BehaviorSubject.create()
但我不能这样做。 IDE抛出一个错误: -
user.onNext(null)
而且这样做,IDE说你永远不会为空: -
user.filter(u -> u!=null)
答
非常感谢你所有的答案,但我最终凭借这个解决方案去: - (VAL用户:用户)
类UserEnvelope {}
而在观测用这个。
这最适合我的要求。
我是Kotlin的新手,所以我不知道如何使用Optionals。但根据我的理解,每次我需要观察值时,我都必须将它转换为用户类型。
答
如果使用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
将由科特林编译器要考虑,因此,你不能传递空。
即使你能,在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
你必须伪造它这样的事情。例如通过创建代表您的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
概念,也许认为另一个解决方案,这是没有必要的。
答
由于Guenhter解释,这是不可能的。然而,而不是提出的空对象模式,我建议你在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()
在这里使用空对象模式会导致比解决它更多的错误。
即使在Java中,'.onNext(null)'也将不会评估为'.onError(new NullPointerException(...))'。 – ephemient
在RxJava 1中有可能。但在2它不是。 –
顺便说一句:你的代码甚至没有编译。请在这里只发布有效的代码。你可以编辑帖子来解决这个问题。 – guenhter