你能为None指定类型参数,还是告诉编译器它是一个Option [String]?

时间:2014-07-17 02:23:31

标签: scala types

我想知道我是否可以在我的代码中写出这样的内容:

None[String]

4 个答案:

答案 0 :(得分:37)

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

scala> Option.empty[String]
res0: Option[String] = None

请注意,在许多情况下,只需使用None预期Option[String]即可。 换句话说,(如Aleksey Izmailov所示),以下是正确的:

def f(o: Option[String]) = ...; f(None)

这是因为None扩展了Option[Nothing],因此Option是协变的(并且Nothing是其他所有类型的子类型),{{1对于任何None,始终与Option[T]兼容。

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

T

答案 1 :(得分:8)

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

... sealed abstract class Option[+A] ...

它被另外两个类扩展:

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是一个密封的抽象类,因此您无法扩展它。您不能扩展其子类SomeNone,因为它们是案例类。

通常,您甚至不需要尝试编写类似None[String]的内容,因为在上下文中的某处定义了更具体的Option类型。例如,作为函数参数:

def f(o: Option[String]) = ...; f(None)

或作为改进:

val o: Option[String] = None

此外,你真的不关心Option是什么类型,如果它是Nothing值,你无论如何也无法得到任何东西,它就像Java中的null但是有Monadic行为。

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

final def none[A]: Option[A] = None

答案 2 :(得分:7)

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

  

无:选项[字符串]

冒号是显式类型注释。

答案 3 :(得分:1)

你可以使用scalaz:

import scalaz._
import Scalaz._

none[String]  // res0: Option[String] = None