Библиотечная поддержка свойства Scala NotNull

Примечание. Начиная с Scala 2.11, NotNull устарел.

Насколько я понимаю, если вы хотите, чтобы ссылочный тип не допускал значения NULL, вам нужно подмешать волшебный признак NotNull, и компилятор автоматически запретит вам помещать в него null-способные значения. См., Например, эту ветку списка рассылки.

Чего не хватает, так это достойной поддержки библиотек для типов, не допускающих значения NULL. Если я хочу написать пакет, которому не нужно напрямую связывать Java-код, и я хочу запретить всем типам в этом пакете использовать null по умолчанию, у меня нет другого выбора, кроме как переопределить все такие переменные построения

//can't actually do that, but just to give the general idea
class NString extends String with NotNull
class NMap[X,Y] extends Map[X,Y] with NotNull
...

Я ожидаю, что в scala будет (как плагин компилятора или библиотека) возможность писать

import collections.notnull._

для того, чтобы легко запретить null использование в конкретном файле scala.

Есть ли возможность легко заставить многие полезные типы в стандартной библиотеке не допускать значения NULL?


person Elazar Leibovich    schedule 05.10.2009    source источник
comment
Вы можете расширить String? Я думал, что это было окончательно.   -  person Mitch Blevins    schedule 09.10.2009
comment
На самом деле вы не можете. Хорошая точка зрения. Думаю, нужно определить NString с неявным преобразованием в строку.   -  person Elazar Leibovich    schedule 09.10.2009
comment
Думаю, вы ищете что-то вроде org.jetbrains.annotations.NotNull - и я тоже скучаю по нему.   -  person Martin    schedule 16.02.2013
comment
проверить решение, предложенное в этом ответе   -  person Mortimer    schedule 04.09.2013


Ответы (1)


Я действительно не знаю, в чем дело с NotNull, но у меня складывается впечатление, что Scala еще не полностью проработала, как она хочет работать с концепциями NotNull / Nullable. Моя собственная политика - никогда не использовать null в Scala, и если вы вызываете Java API, который может возвращать null, немедленно преобразуйте его в Option.

Этот служебный метод - мой лучший друг:

def ?[A <: AnyRef](nullable: A): Option[A] = if (nullable eq null) None else Some(nullable)

Затем вы делаете что-то вроде этого:

val foo: Option[Foo] = ?(getFooFromJavaAPIThatMightReturnNull())

Я считаю это намного проще, чем пытаться отследить, что может быть, а что нет.

Так что я вообще не ответил на ваш вопрос, но передам это, если это будет полезно ...

Обновление: более поздние версии Scala теперь поддерживают это в стандартном API:

val foo: Option[Foo] = Option(getFooFromJavaAPIThatMightReturnNull())
person Lachlan    schedule 06.11.2009
comment
Проблема с вашим подходом в том, что система типов не заставляет меня не использовать null. Таким образом, я могу забыть о вызове Java API и незаметно проникнуть в мой код нулевым значением. Если все типы OTOH имеют значение NotNullable, компилятор закричит, если вы сделаете val x: String с NotNullable = javaapithatmightreturnNull (). - person Elazar Leibovich; 06.11.2009
comment
Option.apply выполняет те же действия, что и ваша ? функция. - person schmmd; 22.05.2012
comment
Действительно, но это было написано до того, как появился Option.apply. - person Lachlan; 12.06.2012
comment
Использование Option - это общепринятый метод работы с функциями, которые могут ничего не возвращать, но это по-прежнему означает, что вам приходится иметь дело со случаями, когда foo возвращает None и изменять код, вызывающий foo на match или map на Option. Если вы знаете, что foo действительно никогда не вернет null, то это зря усложняет ваш код. Использование простого тега Foo with NotNull дает вам семантику, необходимую компилятору для выполнения дополнительных проверок, не требуя от вас ничего менять в вызывающем коде. См. Решение в этом ответе. - person Mortimer; 04.09.2013