详解Scala的Option的模式匹配

时间:2023-01-29 05:51:41
在阅读Spark源码时出现很多Option[T]的写法,实际上这是Option[T]其实代表的是一个数据Scala 试图通过摆脱 null 来解决这个问题,并提供自己的类型用来表示一个值是可选的(有值或无值), 这就是 Option[A] 特质。

Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。

先看看Option中Some与None的源码:

/** Class `Some[A]` represents existing values of type
* `A`.
*
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
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
*/
case object None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}

Option类其实是一个sealed class,None是一个case object,Some是case class,它们同都extends Option类。


Option使用场景在Scala的Map API 中的使用Option[T],获取数据的返回。

map中get方法的源码

def get(key: A): Option[B]

1、操作map中的数据,需要频繁地调用get方法

object TestOption {
def main(args: Array[String]): Unit = {
val bigDataSkills =
Map("Java" -> "first",
"Hadoop" -> "second",
"Spark" -> "third",
"storm" -> "forth",
"hbase" -> "fifth",
"hive" -> "sixth",
"photoshop" -> null)

println(bigDataSkills.get("Java") == Some("first"))
println(bigDataSkills.get("photoshop").get == null)
println(bigDataSkills.get("Spark").get == "third")
println(bigDataSkills.get("abc123") == None)

}
}



2、通过模式匹配操作map中的数据,这是一个非常函数化的概念,它允许有效地 “启用” 类型和/或值,更不用说在定义中将值绑定到变量、在 Some() 和 None 之间切换,以及提取 Some 的值(而不需要调用麻烦的 get() 方法)。
object TestOption2 {
def main(args: Array[String]): Unit = {
val bigDataSkills =
Map("Java" -> "first",
"Hadoop" -> "second",
"Spark" -> "third",
"storm" -> "forth",
"hbase" -> "fifth",
"hive" -> "sixth",
"photoshop" -> null)

def show(value: Option[String]) =
{
value match {
case Some(a) => a
case None => "No this Skill"
}
}

println(show(bigDataSkills.get("Java")) == "first")
println(show(bigDataSkills.get("photoshop")) == null)
println(show(bigDataSkills.get("Spark")) == "third")
println(show(bigDataSkills.get("abc123"))== "No this Skill")

}
}