Я инициализирую свою переменную следующим образом:
val user: BehaviorSubject<User?> user = BehaviorSubject.create()
Но я не могу этого сделать. IDE выдает ошибку: –
user.onNext(null)
И, делая это, IDE говорит, что u никогда не будет null:
user.filter( u -> u!=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
концепции и, возможно, подумайте о другом решении, где это не нужно.
Большое спасибо за все ваши ответы, но я в конечном итоге пошел с этим решением: –
class UserEnvelope (private val: User?) {}
И используйте BehaviorSubject
Это лучше всего соответствовало моим требованиям.
Теперь о Optionals, я не уверен, но я не думаю, что могу заставить тип быть пользователем, и мне пришлось бы вводить листинг каждый раз, когда мне нужно получить к нему доступ. Я ошибаюсь? Я новичок в Котлине.
Большое спасибо за все ваши ответы, но я в конечном итоге пошел с этим решением: –
class UserEnvelope (val user: User?) {}
И используя это в наблюдаемых.
Это лучше всего соответствовало моим требованиям.
Я новичок в Kotlin, поэтому я не знаю, как использовать опционные. Но из того, что я понимаю, мне пришлось бы прибегать к типу «Тип пользователя» каждый раз, когда мне нужно было правильно соблюдать эти ценности?