Интересно, могу ли я написать что-то вроде этого в моем коде:
None[String]
Интересно, могу ли я написать что-то вроде этого в моем коде:
None[String]
Я удивлен, что никто не упоминал о существовании Option.empty
:
scala> Option.empty[String]
res0: Option[String] = None
Обратите внимание, что во многих случаях просто использовать None
, где ожидается Option[String]
, будет работать нормально.
Или, другими словами, (как показывает Алексей Измайлов), следующее верно:
def f(o: Option[String]) = ...; f(None)
Это связано с тем, что None
расширяет Option[Nothing]
, поэтому в силу Option
, являющегося ковариантным (и Nothing
является подтипом любого другого типа), None
всегда совместим с Option[T]
для любого T
.
Это также объясняет, что тип ascription также является прекрасной альтернативой (для случаев, когда вам нужно быть явным в типе опций, например, если это необходимо для ввода вывода типа):
scala> None: Option[String]
res0: Option[String] = None
Option
является параметризованным типом и определяется как таковой:
... sealed abstract class Option[+A] ...
он распространяется на 2 других класса:
final case class Some[+A](x: A) extends Option[A]
и
case object None extends Option[Nothing]
В то время как Some
может принимать любой тип аргумента, None
- специальный экземпляр/синглтон Option
, параметризованный с помощью Nothing
. Более того, Option
является ковариантным в своем аргументе типа [+A]
, что означает, что Option[Nothing]
можно использовать везде, где Option
с любым другим типом аргумента ожидается, так как Nothing
расширяет все типы в Scala. Поэтому нет необходимости создавать какие-либо другие значения для представления значения Nothing
, для всех случаев будет достаточно одного элемента None
.
В терминах расширяемости Option
является закрытым абстрактным классом, поэтому вы не можете его расширять. Вы не можете расширять свои подклассы Some
и None
, так как они являются классами case.
Обычно вам даже не нужно пытаться написать что-то вроде None[String]
, потому что более конкретный тип Option
определен где-то в контексте. Например, в качестве аргумента функции:
def f(o: Option[String]) = ...; f(None)
или как уточнение:
val o: Option[String] = None
Кроме того, вам действительно все равно, какой тип был опцией, если это значение Nothing
, вы все равно ничего не получите от него, это как null
в Java, но с монадическим поведением.
Было упомянуто, что вы можете сделать что-то подобное в scalaz: None[String]
. Это просто синтаксический сахар, хотя и очень удобный, чтобы уменьшить многословие в некоторых случаях, когда типы должны быть аннотированы. Он определяется как таковой:
final def none[A]: Option[A] = None
Если вы хотите указать тип Option
, вы можете использовать:
Нет: Опция [Строка]
Двойник - это явная аннотация типа.
Вы можете со сказазом:
import scalaz._
import Scalaz._
none[String] // res0: Option[String] = None