Интересно, могу ли я написать что-то вроде этого в моем коде:
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