Rég*_*les 39

我很惊讶没有人提到存在Option.empty:

scala> Option.empty[String]
res0: Option[String] = None
Run Code Online (Sandbox Code Playgroud)

请注意,在许多情况下,仅使用None其中一个Option[String],预计将正常工作.或者换句话说,(如Aleksey Izmailov所示),以下是正确的:

def f(o: Option[String]) = ...; f(None)
Run Code Online (Sandbox Code Playgroud)

这是因为None扩展Option[Nothing],因此通过Option协变(并且Nothing是所有其他类型的子类型),None始终与Option[T]任何类型兼容T.

这也是为什么类型归属也是一个很好的选择(对于你需要明确选项类型的情况,例如,如果需要驱动类型推断):

scala> None: Option[String]
res0: Option[String] = None
Run Code Online (Sandbox Code Playgroud)


yǝs*_*ǝla 8

Option 是参数化类型,定义如下:

... sealed abstract class Option[+A] ...
Run Code Online (Sandbox Code Playgroud)

它被其他2个类扩展:

final case class Some[+A](x: A) extends Option[A]
Run Code Online (Sandbox Code Playgroud)

case object None extends Option[Nothing]
Run Code Online (Sandbox Code Playgroud)

虽然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)
Run Code Online (Sandbox Code Playgroud)

或作为改进:

val o: Option[String] = None
Run Code Online (Sandbox Code Playgroud)

而且,你真的不关心Option是什么类型,如果它是一个Nothing值,你无论如何也无法得到任何东西,它就像nullJava中的一样但具有Monadic行为.

有人提到你可以在scalaz中做类似的事情:none[String].这只是一种语法糖,虽然非常方便,但在某些需要注释类型的情况下,可以减少冗长.它定义如下:

final def none[A]: Option[A] = None
Run Code Online (Sandbox Code Playgroud)


Tim*_*tan 7

如果要指定Option可以使用的类型:

无:选项[字符串]

冒号是显式类型注释.