Использование Null / Nothing / Unit в Scala

Я только что прочитал: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/

Насколько я понимаю, Null – это признак, и его единственный экземпляр имеет значение null .

Когда метод принимает аргумент Null, мы можем передать ему только ссылку Null или null , но не любую другую ссылку, даже если она равна null (например, nullString: String = null ).

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


Я действительно не понимаю, какая разница между использованием Nothing и Unit в качестве типа возврата, поскольку оба не возвращают никакого результата, как узнать, какой из них использовать, когда у меня есть метод, который выполняет регистрацию, например?


У вас есть использование Unit / Null / Nothing как нечто иное, чем тип возврата?

Вы используете только Nothing, если метод никогда не возвращается (что означает, что он не может нормально завершиться путем возврата, он может вызвать исключение). Ничто никогда не создавалось и не существует в пользу системы типов (цитирует Джеймса Ири: «Причина, по которой Scala имеет нижний тип, связана с его способностью выражать отклонения в параметрах типа». ). Из статьи, которую вы связали с:

Другое использование Nothing – это возвращаемый тип для методов, которые никогда не возвращаются. Это имеет смысл, если вы думаете об этом. Если возвращаемым типом метода является Nothing, и нет абсолютно никакого экземпляра Nothing, тогда такой метод никогда не должен возвращаться.

Ваш метод ведения журнала вернет Unit. Существует единица значений, поэтому она может быть фактически возвращена. Из документов API :

Единица является подтипом scala.AnyVal. Существует только одно значение типа Unit, (), и оно не представлено никаким объектом в базовой системе исполнения. Метод с возвращаемым типом Unit аналогичен методу Java, который объявлен void.

Статья, которую вы цитируете, может вводить в заблуждение. Тип Null существует для совместимости с виртуальной машиной Java и, в частности, с Java.

Мы должны учитывать, что Scala :

  • полностью объектно-ориентированное: каждое значение является объектом
  • строго типизировано: каждое значение должно иметь тип
  • необходимо обрабатывать null ссылки на доступ, например, библиотеки Java и код

поэтому становится необходимо определить тип для null значения, который является чертой Null , и имеет null как единственный экземпляр.

Нет ничего особенно полезного в типе Null если вы не являетесь системой типов или не работаете в компиляторе. В частности, я не вижу разумной причины определять параметр типа Null для метода, поскольку вы не можете передать ничего, кроме null

У вас есть использование Unit / Null / Nothing как нечто иное, чем тип возврата?


Unit можно использовать следующим образом:

 def execute(code: => Unit):Unit = { // do something before code // do something after } 

Это позволяет вам выполнить произвольный блок кода для выполнения.


Null может использоваться как нижний тип для любого значения, которое может быть обнулено. Примером может служить следующее:

 implicit def zeroNull[B >: Null] = new Zero[B] { def apply = null } 

Nothing не используется в определении None

 object None extends Option[Nothing] 

Это позволяет назначить None для любого типа параметра, потому что Nothing «расширяет» все.

 val x:Option[String] = None 

Я никогда не использовал тип Null , но вы используете Unit , где вы используете java void . Nothing является особым типом, потому что, как уже упоминал Натан, не может быть ни одного экземпляра Nothing . Nothing является так называемым нижним типом, что означает, что это подтип любого другого типа. Этот (и параметр контравариантного типа) – это то, почему вы можете добавить любое значение в Nil – это List[Nothing] – и тогда список будет иметь этот тип элементов. None также, если тип Option[Nothing] . Каждая попытка получить доступ к значениям внутри такого контейнера вызовет исключение, потому что это единственный верный способ возврата из метода типа Nothing .

если вы используете Nothing , нет необходимости делать (включая консоль печати), если вы что-то делаете, используйте тип вывода Unit

 object Run extends App { //def sayHello(): Nothing = println("hello?") def sayHello(): Unit = println("hello?") sayHello() } 

… то как использовать Nothing ?

 trait Option[E] case class Some[E](value: E) extends Option[E] case object None extends Option[Nothing] 

Ничто не часто используется неявно. В приведенном ниже коде val b: Boolean = if (1 > 2) false else throw new RuntimeException("error") предложение else имеет тип Nothing , который является подclassом Boolean (как и любой другой AnyVal). Таким образом, все присваивание действительно для компилятора, хотя предложение else действительно ничего не возвращает.

Вот пример Nothing from scala.predef :

  def ??? : Nothing = throw new NotImplementedError 

Если вы незнакомы (и поисковые системы не могут найти на нем) ??? является функцией замещения Scala для всего, что еще не реализовано. Точно так же как TODO Котлина.

Вы можете использовать тот же трюк при создании макетных объектов: переопределить неиспользуемые методы с помощью специального метода notUsed . Преимущество не использовать ??? заключается в том, что вы не получите компиляции предупреждений о вещах, которые вы никогда не намерены реализовать.

  • Как перечислить все файлы в подкаталоге в scala?
  • Функции против методов в Scala
  • Как добавить переменную в Scala?
  • Разница между Iterator и Stream в Scala?
  • Использование def, val и var в scala
  • Как построить Uber JAR (FAT JAR) с использованием SBT в IntelliJ IDEA?
  • Подчеркивание в именованных аргументах
  • Как импортировать build.gradle в IntelliJ
  • Отладка Scala-кода с помощью простого-build-инструмента (sbt) и IntelliJ
  • Как вы делаете инъекцию зависимостей с шаблоном Cake без hardcoding?
  • Различия между этими тремя способами определения функции в Scala
  • Давайте будем гением компьютера.