Scala Option怎么用?Scala中的Option类型如何处理null值?

文章导读
Previous Quiz Next Scala 的 Option[ T ] 是给定类型零个或一个元素的容器。Option[T] 可以是 Some[T] 或 None 对象,后者表示缺失的值。例如,Scala 的 Map 的 get 方法如果找到与给定键对应的值,则返
📋 目录
  1. A 使用 getOrElse() 方法
  2. B 使用 isEmpty() 方法
  3. C 使用 map() 方法
  4. D 使用 flatMap() 方法
  5. E 使用 filter() 方法
  6. F 使用 foreach() 方法
  7. G 使用 fold() 方法
  8. H Scala Option 方法
A A

Scala - Options



Previous
Quiz
Next

Scala 的 Option[ T ] 是给定类型零个或一个元素的容器。Option[T] 可以是 Some[T]None 对象,后者表示缺失的值。例如,Scala 的 Map 的 get 方法如果找到与给定键对应的值,则返回 Some(value),否则如果 Map 中未定义该键,则返回 None

Option 类型在 Scala 程序中经常使用,你可以将它与 Java 中表示无值的 null 值进行比较。例如,java.util.HashMap 的 get 方法返回 HashMap 中存储的值,或者如果未找到值则返回 null。

假设我们有一个根据主键从数据库中检索记录的方法。

def findPerson(key: Int): Option[Person]

如果找到记录,该方法将返回 Some[Person],否则返回 None。让我们看下面的程序。

示例

object Demo {
   def main(args: Array[String]) {
      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
      
      println("capitals.get( \"France\" ) : " +  capitals.get( "France" ))
      println("capitals.get( \"India\" ) : " +  capitals.get( "India" ))
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。

命令

>scalac Demo.scala
>scala Demo

输出

capitals.get( "France" ) : Some(Paris)
capitals.get( "India" ) : None

处理可选值的最常见方式是通过模式匹配。例如,尝试下面的程序。

示例

object Demo {
   def main(args: Array[String]) {
      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
      
      println("show(capitals.get( \"Japan\")) : " + show(capitals.get( "Japan")) )
      println("show(capitals.get( \"India\")) : " + show(capitals.get( "India")) )
   }
   
   def show(x: Option[String]) = x match {
      case Some(s) => s
      case None => "?"
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。

命令

>scalac Demo.scala
>scala Demo

输出

show(capitals.get( "Japan")) : Tokyo
show(capitals.get( "India")) : ?

使用 getOrElse() 方法

以下示例程序展示了如何使用 getOrElse() 方法来访问值或在无值时使用默认值。

示例

object Demo {
   def main(args: Array[String]) {
      val a:Option[Int] = Some(5)
      val b:Option[Int] = None 
      
      println("a.getOrElse(0): " + a.getOrElse(0) )
      println("b.getOrElse(10): " + b.getOrElse(10) )
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。

命令

>scalac Demo.scala
>scala Demo

输出

a.getOrElse(0): 5
b.getOrElse(10): 10

使用 isEmpty() 方法

以下示例程序展示了如何使用 isEmpty() 方法检查 option 是否为 None。

示例

object Demo {
   def main(args: Array[String]) {
      val a:Option[Int] = Some(5)
      val b:Option[Int] = None 
      
      println("a.isEmpty: " + a.isEmpty )
      println("b.isEmpty: " + b.isEmpty )
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。

命令

>scalac Demo.scala
>scala Demo

输出

a.isEmpty: false
b.isEmpty: true

使用 map() 方法

map() 方法允许你通过对 Option 值应用一个 function 来转换它。如果 Option 是 Some,则对包含的值应用 function。如果 Option 是 None,则返回 None。

示例

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.map(_ * 2): " + a.map(_ * 2))
      println("b.map(_ * 2): " + b.map(_ * 2))
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

a.map(_ * 2): Some(10)
b.map(_ * 2): None

使用 flatMap() 方法

flatMap() 方法类似于 map(),但它用于应用返回 Option 的 function。这用于链式操作返回 Option 值的情况。请尝试以下使用 flatMap() 方法的示例 -

示例

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.flatMap(x => Some(x * 2)): " + a.flatMap(x => Some(x * 2)))
      println("b.flatMap(x => Some(x * 2)): " + b.flatMap(x => Some(x * 2)))
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

a.flatMap(x => Some(x * 2)): Some(10)
b.flatMap(x => Some(x * 2)): None

使用 filter() 方法

filter() 方法允许你使用 predicate function 过滤 Option 内部的值。如果 Option 是 Some 且 predicate 满足条件,则返回原始 Option。否则,返回 None。请尝试以下使用 filter() 方法的示例 -

示例

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.filter(_ > 3): " + a.filter(_ > 3))
      println("a.filter(_ > 8): " + a.filter(_ > 8))
      println("b.filter(_ > 3): " + b.filter(_ > 3))
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

a.filter(_ > 3): Some(5)
a.filter(_ > 8): None
b.filter(_ > 3): None

使用 foreach() 方法

使用 foreach() 方法,如果你有一个 Some 的 Option,可以对其中的值应用一个 function。如果 Option 是 None,则什么也不发生。此方法用于 side effects。请尝试以下使用 foreach() 方法的示例 -

示例

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      a.foreach(x => println("Value of a: " + x))
      b.foreach(x => println("Value of b: " + x))
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

Value of a: 5

使用 fold() 方法

使用 fold() 方法,你可以在单个表达式中处理 Some 和 None 两种情况。它接受两个 function:一个用于处理 None 情况,一个用于处理 Some 情况。请尝试以下使用 fold() 方法的示例 -

示例

object Demo {
   def main(args: Array[String]) = {
      val a: Option[Int] = Some(5)
      val b: Option[Int] = None
      println("a.fold(0)(_ * 2): " + a.fold(0)(_ * 2))
      println("b.fold(0)(_ * 2): " + b.fold(0)(_ * 2))
   }
}

将上述程序保存为 Demo.scala。使用以下命令编译并执行该程序。

命令

> scalac Demo.scala
> scala Demo

输出

a.fold(0)(_ * 2): 10
b.fold(0)(_ * 2): 0

Scala Option 方法

以下是在处理 Option 时可以使用的重要方法。要获取完整的可用方法列表,请查看 Scala 的官方文档。

序号 方法及描述
1

def get: A

返回 option 的值。

2

def isEmpty: Boolean

如果 option 是 None,则返回 true,否则返回 false。

3

def productArity: Int

此 product 的大小。对于 product A(x_1, ..., x_k),返回 k。

4

def productElement(n: Int): Any

此 product 的第 n 个元素(从 0 开始)。换句话说,对于 product A(x_1, ..., x_k),返回 x_(n+1),其中 0 < n < k。

5

def exists(p: (A) => Boolean): Boolean

如果此 option 非空且将谓词 p 应用于此 Option 的值时返回 true,则返回 true。否则,返回 false。

6

def filter(p: (A) => Boolean): Option[A]

如果此 Option 非空且将谓词 p 应用于此 Option 的值返回 true,则返回此 Option。否则,返回 None。

7

def filterNot(p: (A) => Boolean): Option[A]

如果此 Option 非空且将谓词 p 应用于此 Option 的值返回 false,则返回此 Option。否则,返回 None。

8

def flatMap[B](f: (A) => Option[B]): Option[B]

如果此 Option 非空,则返回将 f 应用于此 Option 的值的计算结果。如果此 Option 为空,则返回 None。

9

def foreach[U](f: (A) => U): Unit

如果 option 非空,则将给定的过程 f 应用于 option 的值。否则,不执行任何操作。

10

def getOrElse[B >: A](default: => B): B

如果 option 非空,则返回 option 的值,否则返回评估 default 的结果。

11

def isDefined: Boolean

如果 option 是 Some 的实例,则返回 true,否则返回 false。

12

def iterator: Iterator[A]

如果 option 非空,则返回一个单例 iterator 返回 Option 的值;如果 option 为空,则返回一个空 iterator。

13

def map[B](f: (A) => B): Option[B]

如果此 Option 非空,则返回一个 Some 包含将 f 应用于此 Option 的值的计算结果。否则返回 None。

14

def orElse[B >: A](alternative: => Option[B]): Option[B]

如果此 Option 非空,则返回此 Option,否则返回评估 alternative 的结果。

15

def orNull

如果 option 非空,则返回 option 的值;如果为空,则返回 null。

scala_collections.htm