Если вы используете это с функциями, которые могут возвращать нуль, вы также можете определить оператор слияния нуль:
class NullOption[A <: AnyRef](a: A) {
def |?|[B >: A](b: => B) = if (a ne null) a else b
}
implicit def null_handling[A <: AnyRef](a: A) = new NullOption(a)
, который работает так же, как и Javascript.(Я использовал |?|
, чтобы не принять его за логическое или логическое, но вы можете использовать ||
, если хотите.) Это работает даже лучше - почти как Option
- если вы добавляете условную карту (здесь с именем ?
- выберите ваше любимое слово или символ):
class NullOption[A <: AnyRef](a: A) {
def |?|[B >: A](b: => B) = if (a ne null) a else b
def ?[C >: Null](f: A => C): C = if (a ne null) f(a) else null
}
implicit def null_handling[A <: AnyRef](a: A) = new NullOption(a)
Тогда вы можете
scala> val s: String = null
s: String = null
scala> val t: String = "foo"
t: String = foo
scala> s?(_.toUpperCase) |?| t |?| { println("I am not executed"); "bar" }
res4: java.lang.String = "foo"
Конечно, ваша система типов не поможет вам вспомнить, что вынужно обрабатывать случаи отсутствия данных, но это может сделать обработку нуля немного более приятной (по крайней мере, пока нет примитивов; с примитивами возвращать нуль-или-примитив на самом деле не имеет смысла).