このように変数を初期化します:
val user: BehaviorSubject<User?> user = BehaviorSubject.create()
しかし、私はこれを行うことはできません。 IDEはエラーをスローします:-
user.onNext(null)
そして、これを行うと、IDEはuが決してnullにならないことを示します:-
user.filter( u -> u!=null)
あなたのすべての答えに感謝しますが、私は最終的にこの解決策に行きました:-
class UserEnvelope(val user:User?) {}
そして、オブザーバブルでこれを使用します。
これは私の要件に最適です。
私はKotlinが初めてなので、オプションの使用方法がわかりません。しかし、私が理解していることから、値を正しく観察する必要があるたびに、ユーザータイプに型キャストする必要がありますか?
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
要素を表すnull
の静的オブジェクトを作成します。
例えば.
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
の概念を避け、これが不要な別のソリューションを考えてみてください。
RxJava 2はnull値をサポートしていないため、使用できる他の解決策がいくつかあります。
Any
クラスインスタンスを生成します。たとえば、Empty.INSTANCE
enumクラス。null値をエミュレートし、enumクラスでフィルタリングします。最後の1つは、私が使用しているもので、以前のソリューションのバリアントであることを好み、専門分野に基づいています。 JetBrainsの友人は、Kotlinのクラスは非常に安価であることを常に強調しているため、これはログに記録されたユーザーとログに記録されていないユーザーを区別する簡単な例です。
abstract class SessionUser
sealed class LoggedUser(val username: String, val password: String) : SessionUser()
sealed class LogoutUser : SessionUser()
private val user = BehaviorSubject.create<SessionUser>()
private val loggedUser =
user.filter { it is LoggedUser }.cast(LoggedUser::class.Java)
fun login(username: String, password: String) {
user.onNext(LoggedUser(username, password))
}
fun logout() {
user.onNext(LogoutUser())
}