2017-07-25 94 views
1

我初始化我的变量是这样的: -如何传递null可观察到的可空类型RxJava 2和科特林

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

但我不能这样做。 IDE抛出一个错误: -

user.onNext(null) 

而且这样做,IDE说你永远不会为空: -

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

即使在Java中,'.onNext(null)'也将不会评估为'.onError(new NullPointerException(...))'。 – ephemient

+1

在RxJava 1中有可能。但在2它不是。 –

+0

顺便说一句:你的代码甚至没有编译。请在这里只发布有效的代码。你可以编辑帖子来解决这个问题。 – guenhter

回答

0

非常感谢你所有的答案,但我最终凭借这个解决方案去: - (VAL用户:用户)

类UserEnvelope {}

而在观测用这个。

这最适合我的要求。

我是Kotlin的新手,所以我不知道如何使用Optionals。但根据我的理解,每次我需要观察值时,我都必须将它转换为用户类型。

4

如果使用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概念,也许认为另一个解决方案,这是没有必要的。

5

由于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() 

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

+0

是的,我想这是最干净的方式(即使我不喜欢Optionals :))。 – guenhter

+1

“可选”的“完整”实现(使用类似java.util.Optional的方法)很短:https://gist.github.com/ephemient/2dec1165b7993e6a6cd7cdfa005fe277 – ephemient

+0

@ephemient有趣的方法! – nhaarman