Использование Null / Nothing / Unit в Scala
Я только что прочитал: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/
Насколько я понимаю, Null
– это признак, и его единственный экземпляр имеет значение null
.
Когда метод принимает аргумент Null, мы можем передать ему только ссылку Null
или null
, но не любую другую ссылку, даже если она равна null (например, nullString: String = null
).
- Подчеркивание в List.filter
- В Scala есть оператор присваивания «=» вызов метода?
- Примеры монады штата Скалаз
- использование аргумента переменной длины в scala
- Почему функции scala ограничены 22 параметрами?
Я просто задаюсь вопросом, в каких случаях использование этой черты Null
может быть полезным. Существует также черта «Ничего», для которой я больше не вижу примеров.
Я действительно не понимаю, какая разница между использованием Nothing и Unit в качестве типа возврата, поскольку оба не возвращают никакого результата, как узнать, какой из них использовать, когда у меня есть метод, который выполняет регистрацию, например?
У вас есть использование Unit / Null / Nothing как нечто иное, чем тип возврата?
- Использование _ в scala lambda-функциях
- Разница между этим и «я» в аннотациях самостоятельного типа?
- Как работает «scala.sys.process» от Scala 2.9?
- Как работает тип Dynamic и как его использовать?
- Откуда возникает «плоская карта, которая имеет ***» идиоматическое выражение в Scala?
- частный против частного
- Скала для странного поведения
- Каковы отношения между Any, AnyVal, AnyRef, Object и как они отображаются при использовании в Java-коде?
Вы используете только 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
. Преимущество не использовать ???
заключается в том, что вы не получите компиляции предупреждений о вещах, которые вы никогда не намерены реализовать.