Scala提取器应用,取消应用和模式匹配

时间:2020-02-23 14:41:46  来源:igfitidea点击:

Scala提取器是一个对象,其成员之一具有称为unapply的方法。
unapply方法匹配一个值并将其拆开。
提取器还定义了用于构建值的apply方法。

考虑一个提取使用空格作为分隔符的名字和姓氏的示例。

firstName.scala

object firstName {
def main(args: Array[String]) {

  println("Apply method : " + apply("Steve", "Smith"));
  println("Unapply method : " + unapply("Steve Smith"));
  println("Unapply method : " + unapply("Rob"));

}

def apply(fname: String, lname: String) = {
  fname + " " + lname
}

def unapply(s: String): Option[(String, String)] = {
  val pts = s split " "
  if (pts.length == 2) {
    Some(pts(0), pts(1))
  } else {
    None
  }
}
}

对象firstName定义了两个方法apply和unapply。
apply方法变成一个对象,该对象接受括号内指定的参数并构建该方法中指定的值。
返回的名字和姓氏以及两者之间的空格。

unapply方法将firstname对象返回到提取器中,并按方法中指定的方式断开参数。
unapply方法接受String参数,并以空格作为分隔符分割String并在成对的字符串中返回选项类型。
如果将名字和姓氏作为参数传递,则结果是一对字符串,否则不返回。

下图显示了以上scala程序产生的输出。

Scala提取器模式匹配

如果类的实例包含零个或者多个参数的列表,则编译器将对该实例调用apply方法。
可以为对象和类都定义apply方法。

考虑如下所示的示例;

patternmatch.scala

case class Student(name: String, address: Seq[Address])
case class Address(city: String, state: String)

object City {
def unapply(s: Student): Option[Seq[String]] =
  Some(
    for (c <- s.address)
      yield c.state)
}

class StringSeqContains(value: String) {
def unapply(in: Seq[String]): Boolean =
  in contains value
}

object PatternMatch {
def main(args: Array[String]) {

  val stud = List(Student("Harris", List(Address("LosAngeles", "California"))),
    Student("Reena", List(Address("Houston", "Texas"))),
    Student("Rob", List(Address("Dallas", "Texas"))),
    Student("Chris", List(Address("Hymansonville", "Florida"))))

  val Texas = new StringSeqContains("Texas")
  val students = stud collect {
    case student @ City(Texas()) => student.name
  }
  println(students)
}
}

在上面的示例中,我们定义了两个类Student和Address。
学生班包含姓名和地址,而地址包含城市和州。

在对象City中,我们定义了一个未应用的方法,该方法从地址列表中获取状态。
在PatternMatch对象中,我们创建Student和address的对象,并获取留在得克萨斯城的学生的姓名,这是要匹配的模式。