scala Option原理示例源码分析
文章目录
原理
Scala的Option类型是受到Haskell语言中Maybe类型的启发而来。在函数式编程中,处理可能存在或不存在值的情况是一个常见的需求。Option提供了一种优雅的方式来表示这种情况,并且通过编译时类型检查来避免空指针异常。
Option的基本原理如下:
- Option是一个容器类型,它可以包含一个值或者不包含任何值。
- Option有两个子类:Some和None。
- Some表示Option中存在一个值,它将值封装在Some对象中。
- None表示Option中不存在值,它是一个单例对象。
- 使用Option可以有效地避免使用null来表示缺少值的情况。null具有特殊含义,并且在使用过程中容易引发空指针异常。
- Option提供了一组方法来操作Option中的值:
- getOrElse:获取Option中的值,如果不存在则返回默认值。
- map:对Option中的值进行转换,返回新的Option。
- flatMap:对Option中的值进行转换,返回新的Option,并且可以扁平化嵌套的Option结构。
- filter:对Option中的值进行过滤,返回新的Option。
- 等等。
- 使用Option可以使代码更加健壮和安全,因为它强制我们在处理可能不存在的值时进行明确的处理。
总结起来,Option的基本原理是通过Some和None来表示可能存在或不存在的值,避免了使用null并提供了一组方法来操作Option中的值。这种方式能够增加代码的可读性、可靠性和安全性,减少空指针异常的风险。
方法总结
以下是Option常用方法的总结:
isEmpty
:判断Option是否为None。isDefined
:判断Option是否为Some。get
:获取Option中的值,如果Option为None,则抛出NoSuchElementException异常。getOrElse
:获取Option中的值,如果Option为None,则返回提供的默认值。orElse
:返回当前Option对象,如果Option为None,则返回提供的备选Option对象。map
:对Option中的值进行映射操作,并返回新的Option。如果Option为None,则直接返回None;如果Option为Some,则将映射函数应用于值并包装成Some返回。flatMap
:对Option中的值进行映射操作,并返回新的Option,可以扁平化嵌套的Option结构。如果Option为None,则直接返回None;如果Option为Some,则将映射函数应用于值并返回结果Option。filter
:根据给定的条件对Option中的值进行过滤,并返回新的Option。如果Option为None或不满足条件,则直接返回None;如果Option为Some且满足条件,则返回原始Some。foreach
:对Option中的值应用指定的函数。如果Option为Some,则将函数应用于值;如果Option为None,则不执行任何操作。fold
:将Option分为两种情况处理,根据Option是否为空来执行不同的操作。如果Option为None,则返回提供的默认值;如果Option为Some,则将值应用于给定的函数。contains
:判断Option中是否包含给定的元素。如果Option为Some且与给定元素相等,则返回true;否则返回false。exists
:判断Option中的值是否满足给定的条件。如果Option为Some且满足条件,则返回true;否则返回false。forall
:判断Option中的值是否都满足给定的条件。如果Option为None,则直接返回true;如果Option为Some且所有值都满足条件,则返回true;否则返回false。
这些方法可以帮助我们更方便、安全地处理可能为空的值,避免了空指针异常,并提供了一些常用的操作和转换方式。使用Option能够使代码更加健壮、可读性更高,并提高程序的安全性。
示例
以下是对每个Option方法的示例代码:
// Option对象示例
val option: Option[Int] = Some(10)
val noneOption: Option[Int] = None
// isEmpty和isDefined
println(option.isEmpty) // false
println(option.isDefined) // true
println(noneOption.isEmpty) // true
println(noneOption.isDefined) // false
// get
println(option.get) // 10
// println(noneOption.get) // 抛出NoSuchElementException异常
// getOrElse
val result1 = option.getOrElse(0) // 10
val result2 = noneOption.getOrElse(0) // 0
println(result1)
println(result2)
// orElse
val altOption = Some(20)
val mergedOption = noneOption.orElse(altOption) // Some(20)
println(mergedOption)
// map
val mappedOption = option.map(_ * 2) // Some(20)
val noneMappedOption = noneOption.map(_ * 2) // None
println(mappedOption)
println(noneMappedOption)
// flatMap
val flatMappedOption = option.flatMap(x => if (x > 5) Some(x * 2) else None) // Some(20)
val noneFlatMappedOption = noneOption.flatMap(x => if (x > 5) Some(x * 2) else None) // None
println(flatMappedOption)
println(noneFlatMappedOption)
// filter
val filteredOption = option.filter(_ > 5) // Some(10)
val noneFilteredOption = option.filter(_ > 15) // None
println(filteredOption)
println(noneFilteredOption)
// foreach
option.foreach(x => println(x)) // 输出:10
// fold
val foldedResult1 = option.fold(0)(_ * 2) // 20
val foldedResult2 = noneOption.fold(0)(_ * 2) // 0
println(foldedResult1)
println(foldedResult2)
// contains
val isContained1 = option.contains(10) // true
val isContained2 = option.contains(15) // false
println(isContained1)
println(isContained2)
// exists
val doesExist1 = option.exists(_ > 5) // true
val doesExist2 = option.exists(_ > 15) // false
println(doesExist1)
println(doesExist2)
// forall
val forAll1 = option.forall(_ > 5) // true
val forAll2 = option.forall(_ > 15) // false
println(forAll1)
println(forAll2)
中文源码
1.object Option
object Option {
import scala.language.implicitConversions
/**
* 将 Option 转换为可迭代的值的隐式转换函数
*/
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
/**
* 如果参数不为 null,则返回 Some(x);如果为 null,则返回 None。
*
* @param x 值
* @return 如果 value != null,则返回 Some(value),否则返回 None
*/
def apply[A](x: A): Option[A] = if (x == null) None else Some(x)
/**
* 返回一个与集合层次结构一致的空 Option 对象 None。
*/
def empty[A] : Option[A] = None
}
这段代码是 Scala 标准库中的 Option
对象的定义。Option
是一种表示可能存在或不存在值的容器类型。它有两个子类:Some
表示存在一个值,None
表示不存在值。
这段代码中定义了一个 Option
的伴生对象 Option
,其中包含了一些方法和隐式转换。
- 隐式转换
option2Iterable
:
这个隐式转换允许将Option[A]
类型的对象转换为Iterable[A]
类型的对象。它的实现通过调用xo.toList
将Option
转换为List
,然后再将List
转换为Iterable
。 apply
方法:
这是一个工厂方法,用于创建Option
对象。如果参数x
不为null
,则返回Some(x)
;如果x
为null
,则返回None
。empty
方法:
这是一个工厂方法,返回一个空的Option
对象,即None
。
2. class Option[+A]
/** 表示可选值的类。`Option` 的实例要么是 `Some` 的实例,要么是 `None` 对象。
*
* 使用 `Option` 实例最常见的方式是将其视为集合或单子,并使用 `map`、`flatMap`、`filter` 或 `foreach` 等方法进行操作:
*
* {{{
* val name: Option[String] = request getParameter "name"
* val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
* println(upper getOrElse "")
* }}}
*
* 注意,这与以下代码是等价的:
*
* {{{
* val upper = for {
* name <- request getParameter "name"
* trimmed <- Some(name.trim)
* upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
* } yield upper
* println(upper getOrElse "")
* }}}
*
* 因为 `for` 推导式的工作原理,如果 `request.getParameter` 返回 `None`,整个表达式结果将是 `None`。
*
* 这样可以方便地链式处理 `Option` 值,而不必检查是否存在值。
*
* 另一种使用 `Option` 值的方法是通过模式匹配:
*
* {{{
* val nameMaybe = request getParameter "name"
* nameMaybe match {
* case Some(name) =>
* println(name.trim.toUppercase)
* case None =>
* println("No name value")
* }
* }}}
*
* 注意:这里的许多方法与 Traversable 层次结构中的方法重复,但出于以下原因而重复:隐式转换往往会将可选值转换为可迭代对象(Iterable),但我们可能更希望保留 `Option` 值。
*
* 作者:Martin Odersky、Matthias Zenger
* 版本:1.1,16/01/2007
*/
@SerialVersionUID(-114498752079829388L)
sealed abstract class Option[+A] extends Product with Serializable {
self =>
// 判断选项是否为空
def isEmpty: Boolean
// 判断选项是否为定义(非空)
def isDefined: Boolean = !isEmpty
// 获取选项的值,如果选项为空则抛出异常
def get: A
// 获取选项的值,如果选项为空则返回默认值
def getOrElse[B >: A](default: => B): B =
if (isEmpty) default else this.get
// 将选项转换为 null 或者选项的值
def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse ev(null)
// 将选项的值应用于函数,并返回新的选项
def map[B](f: A => B): Option[B] =
if (isEmpty) None else Some(f(this.get))
// 对选项进行折叠操作,如果为空则返回 ifEmpty,否则返回 f 对选项的值应用的结果
def fold[B](ifEmpty: => B)(f: A => B): B =
if (isEmpty) ifEmpty else f(this.get)
// 对选项的值应用一个返回选项的函数,并返回新的选项
def flatMap[B](f: A => Option[B]): Option[B] =
if (isEmpty) None else f(this.get)
// 扁平化操作,将嵌套的选项展开为单层选项
def flatten[B](implicit ev: A <:< Option[B]): Option[B] =
if (isEmpty) None else ev(this.get)
// 根据给定的条件对选项进行过滤,返回符合条件的选项
def filter(p: A => Boolean): Option[A] =
if (isEmpty || p(this.get)) this else None
// 根据给定的条件对选项进行过滤,返回不符合条件的选项
def filterNot(p: A => Boolean): Option[A] =
if (isEmpty || !p(this.get)) this else None
final def nonEmpty = isDefined
// 过滤器方法,用于支持 for 推导式中的条件过滤
final def withFilter(p: A => Boolean): WithFilter = new WithFilter(p)
class WithFilter(p: A => Boolean) {
def map[B](f: A => B): Option[B] = self filter p map f
def flatMap[B](f: A => Option[B]): Option[B] = self filter p flatMap f
def foreach[U](f: A => U): Unit = self filter p foreach f
def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x))
}
// 判断选项是否包含给定的元素
final def contains[A1 >: A](elem: A1): Boolean =
!isEmpty && this.get == elem
// 判断选项的值是否满足给定的条件
final def exists(p: A => Boolean): Boolean =
!isEmpty && p(this.get)
// 判断选项的值是否都满足给定的条件
final def forall(p: A => Boolean): Boolean = isEmpty || p(this.get)
// 对选项的值应用一个函数
final def foreach[U](f: A => U) {
if (!isEmpty) f(this.get)
}
// 根据偏函数对选项进行收集,返回新的选项
final def collect[B](pf: PartialFunction[A, B]): Option[B] =
if (!isEmpty) pf.lift(this.get) else None
// 返回当前选项或替代选项,如果为空则返回替代选项
final def orElse[B >: A](alternative: => Option[B]): Option[B] =
if (isEmpty) alternative else this
// 将选项转换为迭代器
def iterator: Iterator[A] =
if (isEmpty) collection.Iterator.empty else collection.Iterator.single(this.get)
// 将选项转换为只包含选项值的单元素列表,如果选项非空则返回该列表,否则返回空列表
def toList: List[A] =
if (isEmpty) List() else new ::(this.get, Nil)
// 如果选项为空,则返回一个包含给定参数 `left` 的 Left;如果选项非空,则返回一个包含选项值的 Right
@inline final def toRight[X](left: => X) =
if (isEmpty) Left(left) else Right(this.get)
// 如果选项为空,则返回一个包含给定参数 `right` 的 Right;如果选项非空,则返回一个包含选项值的 Left
@inline final def toLeft[X](right: => X) =
if (isEmpty) Right(right) else Left(this.get)
这段代码定义了一个抽象类 Option[+A]
,它表示一个可能存在或不存在值的选项。这是一个用于处理可能存在或不存在值的选项的类。以下是它的一些重要方法:
isEmpty
方法返回一个布尔值,指示该选项是否为空。isDefined
方法返回一个布尔值,指示该选项是否为定义(非空)。get
方法返回选项的值。如果选项为空,则抛出NoSuchElementException
异常。getOrElse
方法返回选项的值,如果选项为空则返回默认值。map
方法将一个函数应用于选项的值,并返回新的选项。flatMap
方法将一个返回选项的函数应用于选项的值,并返回新的选项。filter
方法根据给定的条件对选项进行过滤,返回符合条件的选项。foreach
方法将一个函数应用于选项的值(如果非空)。contains
方法检查选项是否包含给定的元素。orElse
方法返回当前选项,如果为空,则返回替代选项。toList
方法将选项转换为列表。
3.case class Some
Option
类提供了一种安全地处理可能为空的值的方式,可以避免空指针异常。它有两个子类:Some
和 None
,分别表示存在值。这段代码定义了 Option
对象的两个子类:Some
和 None
。
/** Class `Some[A]` represents existing values of type
* `A`.
*
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
@SerialVersionUID(1234815782226070388L)
final case class Some[+A](x: A) extends Option[A] {
def isEmpty = false
def get = x
}
Some[A]
是一个表示存在值的类。它是Option[A]
的子类。x
是Some
类的一个字段,表示存在的值。isEmpty
方法返回false
,表示该Some
对象不为空。get
方法返回存储的值x
。
4.case object None
/** 这个案例对象表示不存在的值
*
* 作者:Martin Odersky
* 版本:1.0, 16/07/2003
*/
@SerialVersionUID(5066590221178148012L)
case object None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}
None
是一个表示不存在值的单例对象。它是Option[Nothing]
的子类。isEmpty
方法返回true
,表示该None
对象为空。get
方法抛出NoSuchElementException
异常,因为None
中没有存储任何值。
Some
和 None
是 Option
类型的两种特殊情况,用于表示可能存在或不存在值的情况。Some
用于表示存在一个值,而 None
用于表示不存在值。通过使用这两个子类对象,可以更好地处理可能为空的值,并且可以在代码中进行模式匹配和安全访问。
英文源码
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala
object Option {
import scala.language.implicitConversions
/** An implicit conversion that converts an option to an iterable value
*/
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
/** An Option factory which creates Some(x) if the argument is not null,
* and None if it is null.
*
* @param x the value
* @return Some(value) if value != null, None if value == null
*/
def apply[A](x: A): Option[A] = if (x == null) None else Some(x)
/** An Option factory which returns `None` in a manner consistent with
* the collections hierarchy.
*/
def empty[A] : Option[A] = None
}
/** Represents optional values. Instances of `Option`
* are either an instance of $some or the object $none.
*
* The most idiomatic way to use an $option instance is to treat it
* as a collection or monad and use `map`,`flatMap`, `filter`, or
* `foreach`:
*
* {{{
* val name: Option[String] = request getParameter "name"
* val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
* println(upper getOrElse "")
* }}}
*
* Note that this is equivalent to {{{
* val upper = for {
* name <- request getParameter "name"
* trimmed <- Some(name.trim)
* upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
* } yield upper
* println(upper getOrElse "")
* }}}
*
* Because of how for comprehension works, if $none is returned
* from `request.getParameter`, the entire expression results in
* $none
*
* This allows for sophisticated chaining of $option values without
* having to check for the existence of a value.
*
* A less-idiomatic way to use $option values is via pattern matching: {{{
* val nameMaybe = request getParameter "name"
* nameMaybe match {
* case Some(name) =>
* println(name.trim.toUppercase)
* case None =>
* println("No name value")
* }
* }}}
*
* @note Many of the methods in here are duplicative with those
* in the Traversable hierarchy, but they are duplicated for a reason:
* the implicit conversion tends to leave one with an Iterable in
* situations where one could have retained an Option.
*
* @author Martin Odersky
* @author Matthias Zenger
* @version 1.1, 16/01/2007
* @define none `None`
* @define some [[scala.Some]]
* @define option [[scala.Option]]
* @define p `p`
* @define f `f`
* @define coll option
* @define Coll `Option`
* @define orderDependent
* @define orderDependentFold
* @define mayNotTerminateInf
* @define willNotTerminateInf
* @define collectExample
* @define undefinedorder
* @define thatinfo the class of the returned collection. In the standard library configuration, `That` is `Iterable[B]`
* @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current
* representation type `Repr` and the new element type `B`.
*/
@SerialVersionUID(-114498752079829388L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
sealed abstract class Option[+A] extends Product with Serializable {
self =>
/** Returns true if the option is $none, false otherwise.
*/
def isEmpty: Boolean
/** Returns true if the option is an instance of $some, false otherwise.
*/
def isDefined: Boolean = !isEmpty
/** Returns the option's value.
* @note The option must be nonEmpty.
* @throws java.util.NoSuchElementException if the option is empty.
*/
def get: A
/** Returns the option's value if the option is nonempty, otherwise
* return the result of evaluating `default`.
*
* @param default the default expression.
*/
@inline final def getOrElse[B >: A](default: => B): B =
if (isEmpty) default else this.get
/** Returns the option's value if it is nonempty,
* or `null` if it is empty.
* Although the use of null is discouraged, code written to use
* $option must often interface with code that expects and returns nulls.
* @example {{{
* val initialText: Option[String] = getInitialText
* val textField = new JComponent(initialText.orNull,20)
* }}}
*/
@inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse ev(null)
/** Returns a $some containing the result of applying $f to this $option's
* value if this $option is nonempty.
* Otherwise return $none.
*
* @note This is similar to `flatMap` except here,
* $f does not need to wrap its result in an $option.
*
* @param f the function to apply
* @see flatMap
* @see foreach
*/
@inline final def map[B](f: A => B): Option[B] =
if (isEmpty) None else Some(f(this.get))
/** Returns the result of applying $f to this $option's
* value if the $option is nonempty. Otherwise, evaluates
* expression `ifEmpty`.
*
* @note This is equivalent to `$option map f getOrElse ifEmpty`.
*
* @param ifEmpty the expression to evaluate if empty.
* @param f the function to apply if nonempty.
*/
@inline final def fold[B](ifEmpty: => B)(f: A => B): B =
if (isEmpty) ifEmpty else f(this.get)
/** Returns the result of applying $f to this $option's value if
* this $option is nonempty.
* Returns $none if this $option is empty.
* Slightly different from `map` in that $f is expected to
* return an $option (which could be $none).
*
* @param f the function to apply
* @see map
* @see foreach
*/
@inline final def flatMap[B](f: A => Option[B]): Option[B] =
if (isEmpty) None else f(this.get)
def flatten[B](implicit ev: A <:< Option[B]): Option[B] =
if (isEmpty) None else ev(this.get)
/** Returns this $option if it is nonempty '''and''' applying the predicate $p to
* this $option's value returns true. Otherwise, return $none.
*
* @param p the predicate used for testing.
*/
@inline final def filter(p: A => Boolean): Option[A] =
if (isEmpty || p(this.get)) this else None
/** Returns this $option if it is nonempty '''and''' applying the predicate $p to
* this $option's value returns false. Otherwise, return $none.
*
* @param p the predicate used for testing.
*/
@inline final def filterNot(p: A => Boolean): Option[A] =
if (isEmpty || !p(this.get)) this else None
/** Returns false if the option is $none, true otherwise.
* @note Implemented here to avoid the implicit conversion to Iterable.
*/
final def nonEmpty = isDefined
/** Necessary to keep $option from being implicitly converted to
* [[scala.collection.Iterable]] in `for` comprehensions.
*/
@inline final def withFilter(p: A => Boolean): WithFilter = new WithFilter(p)
/** We need a whole WithFilter class to honor the "doesn't create a new
* collection" contract even though it seems unlikely to matter much in a
* collection with max size 1.
*/
class WithFilter(p: A => Boolean) {
def map[B](f: A => B): Option[B] = self filter p map f
def flatMap[B](f: A => Option[B]): Option[B] = self filter p flatMap f
def foreach[U](f: A => U): Unit = self filter p foreach f
def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x))
}
/** Tests whether the option contains a given value as an element.
*
* @example {{{
* // Returns true because Some instance contains string "something" which equals "something".
* Some("something") contains "something"
*
* // Returns false because "something" != "anything".
* Some("something") contains "anything"
*
* // Returns false when method called on None.
* None contains "anything"
* }}}
*
* @param elem the element to test.
* @return `true` if the option has an element that is equal (as
* determined by `==`) to `elem`, `false` otherwise.
*/
final def contains[A1 >: A](elem: A1): Boolean =
!isEmpty && this.get == elem
/** Returns true if this option is nonempty '''and''' the predicate
* $p returns true when applied to this $option's value.
* Otherwise, returns false.
*
* @param p the predicate to test
*/
@inline final def exists(p: A => Boolean): Boolean =
!isEmpty && p(this.get)
/** Returns true if this option is empty '''or''' the predicate
* $p returns true when applied to this $option's value.
*
* @param p the predicate to test
*/
@inline final def forall(p: A => Boolean): Boolean = isEmpty || p(this.get)
/** Apply the given procedure $f to the option's value,
* if it is nonempty. Otherwise, do nothing.
*
* @param f the procedure to apply.
* @see map
* @see flatMap
*/
@inline final def foreach[U](f: A => U) {
if (!isEmpty) f(this.get)
}
/** Returns a $some containing the result of
* applying `pf` to this $option's contained
* value, '''if''' this option is
* nonempty '''and''' `pf` is defined for that value.
* Returns $none otherwise.
*
* @example {{{
* // Returns Some(HTTP) because the partial function covers the case.
* Some("http") collect {case "http" => "HTTP"}
*
* // Returns None because the partial function doesn't cover the case.
* Some("ftp") collect {case "http" => "HTTP"}
*
* // Returns None because the option is empty. There is no value to pass to the partial function.
* None collect {case value => value}
* }}}
*
* @param pf the partial function.
* @return the result of applying `pf` to this $option's
* value (if possible), or $none.
*/
@inline final def collect[B](pf: PartialFunction[A, B]): Option[B] =
if (!isEmpty) pf.lift(this.get) else None
/** Returns this $option if it is nonempty,
* otherwise return the result of evaluating `alternative`.
* @param alternative the alternative expression.
*/
@inline final def orElse[B >: A](alternative: => Option[B]): Option[B] =
if (isEmpty) alternative else this
/** Returns a singleton iterator returning the $option's value
* if it is nonempty, or an empty iterator if the option is empty.
*/
def iterator: Iterator[A] =
if (isEmpty) collection.Iterator.empty else collection.Iterator.single(this.get)
/** Returns a singleton list containing the $option's value
* if it is nonempty, or the empty list if the $option is empty.
*/
def toList: List[A] =
if (isEmpty) List() else new ::(this.get, Nil)
/** Returns a [[scala.util.Left]] containing the given
* argument `left` if this $option is empty, or
* a [[scala.util.Right]] containing this $option's value if
* this is nonempty.
*
* @param left the expression to evaluate and return if this is empty
* @see toLeft
*/
@inline final def toRight[X](left: => X) =
if (isEmpty) Left(left) else Right(this.get)
/** Returns a [[scala.util.Right]] containing the given
* argument `right` if this is empty, or
* a [[scala.util.Left]] containing this $option's value
* if this $option is nonempty.
*
* @param right the expression to evaluate and return if this is empty
* @see toRight
*/
@inline final def toLeft[X](right: => X) =
if (isEmpty) Right(right) else Left(this.get)
}
/** Class `Some[A]` represents existing values of type
* `A`.
*
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
@SerialVersionUID(1234815782226070388L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
final case class Some[+A](x: A) extends Option[A] {
def isEmpty = false
def get = x
}
/** This case object represents non-existent values.
*
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
@SerialVersionUID(5066590221178148012L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
case object None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}