SFC2020
SFC2020 管理员

554枚
铜币

689点
威望

0个
银元

scala的提取器对象

2020-05-28 11:00

3460

图片:微信图片_20200417110302.jpg



提取器对象是一个包含有 unapply 方法的单例对象。apply 方法就像一个构造器,接受参数然后创建一个实例对象,反之 unapply 方法接受一个实例对象然后返回最初创建它所用的参数。提取器常用在模式匹配和偏函数中。

import scala.util.Randomobject CustomerID {  def apply(name: String) = s"$name--${Random.nextLong}"  def unapply(customerID: String): Option[String] = {    val stringArray: Array[String] = customerID.split("--")    if (stringArray.tail.nonEmpty) Some(stringArray.head) else None  }}val customer1ID = CustomerID("Sukyoung")  customer1ID match {  case CustomerID(name) => println(name)    case _ => println("Could not extract a CustomerID")}

这里 apply 方法用 name 创建一个 CustomerID 字符串。而 unapply 方法正好相反,它返回name 。当我们调用 CustomerID("Sukyoung") ,其实是调用了CustomerID.apply("Sukyoung") 的简化语法。当我们调用 case CustomerID(name) => println(name),就是在调用提取器方法。因为变量定义可以使用模式引入变量,提取器可以用来初始化这个变量,使用 unapply 方法来生成值。

val customer2ID = CustomerID("Nico")val CustomerID(name) = customer2IDprintln(name)

上面的代码等价于 val name = CustomerID.unapply(customer2ID).get。

val CustomerID(name2) = "--asdfasdfasdf"

如果没有匹配的值,会抛出 scala.MatchError:

val CustomerID(name3) = "-asdfasdfasdf"

unapply 方法的返回值应当符合下面的某一条:
  • 如果只是用来判断真假,可以返回一个 Boolean 类型的值。例如 case even()。
  • 如果只是用来提取单个 T 类型的值,可以返回 Option[T]。
  • 如果你想要提取多个值,类型分别为 T1,...,Tn,可以把它们放在一个可选的元组中 Option[(T1,...,Tn)]。

有时,要提取的值的数量不是固定的,因此我们想根据输入来返回随机数量的值。这种情况下,你可以用 unapplySeq 方法来定义提取器,此方法返回 Option[Seq[T]]。常见的例子有,用 case List(x, y, z) => 来解构一个列表 List,以及用一个正则表达式 Regex 来分解一个字符串 String,例如
case r(name, remainingFields @ _*) =>

本文源自浪勺子 大数据群英萃,转载目的在于传递更多信息,版权归原作者所有。


返回顶部