📜  Scala-提取器

📅  最后修改于: 2020-11-02 04:49:42             🧑  作者: Mango


Scala中的提取器是一个对象,该对象具有称为unapply的方法作为其成员之一。该不适用方法的目的是匹配值并将其拆开。通常,提取器对象还定义了适用于构建值的对偶方法,但这不是必需的。

让我们以对象定义的示例为例,定义apply方法和unapply方法。 apply方法的含义一如既往:将Test变成一个对象,该对象可以像应用方法一样应用于括号中的参数。因此,您可以编写Test(“ Zara”,“ gmail.com”)来构造字符串“ Zara@gmail.com”。

unapply方法是将Test类转换为提取器,并逆转apply的构造过程的方法。其中apply接受两个字符串并组成一个电子邮件地址字符串,unapply接受一个电子邮件地址并可能返回两个字符串:用户和地址的

取消应用还必须处理给定字符串不是电子邮件地址的情况。这就是为什么unapply在字符串对上返回Option-type的原因。如果字符串str是具有给定用户和域部分的电子邮件地址,则结果为Some(用户,域) ,或者如果str不是电子邮件地址,则结果为None。以下是一些示例。

句法

unapply("Zara@gmail.com") equals Some("Zara", "gmail.com")
unapply("Zara Ali") equals None

以下示例程序显示了电子邮件地址的提取器对象。

object Demo {
   def main(args: Array[String]) {
      println ("Apply method : " + apply("Zara", "gmail.com"));
      println ("Unapply method : " + unapply("Zara@gmail.com"));
      println ("Unapply method : " + unapply("Zara Ali"));
   }
   
   // The injection method (optional)
   def apply(user: String, domain: String) = {
      user +"@"+ domain
   }

   // The extraction method (mandatory)
   def unapply(str: String): Option[(String, String)] = {
      val parts = str split "@"
      
      if (parts.length == 2){
         Some(parts(0), parts(1)) 
      } else {
         None
      }
   }
}

将以上程序保存在Demo.scala中。以下命令用于编译和执行该程序。

命令

\>scalac Demo.scala
\>scala Demo

输出

Apply method : Zara@gmail.com
Unapply method : Some((Zara,gmail.com))
Unapply method : None

用提取器进行模式匹配

当类的实例后跟带有零个或多个参数的列表的括号时,编译器在该实例上调用apply方法。我们可以在对象和类中定义应用。

如上面提到的,不应用方法的目的是提取我们正在寻找一个特定的值。它相反的操作应用一样。使用match语句比较提取器对象时,将自动执行unapply方法。

请尝试以下示例程序。

object Demo {
   def main(args: Array[String]) {
      val x = Demo(5)
      println(x)

      x match {
         case Demo(num) => println(x+" is bigger two times than "+num)
         
         //unapply is invoked
         case _ => println("i cannot calculate")
      }
   }
   def apply(x: Int) = x*2
   def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}

将以上程序保存在Demo.scala中。以下命令用于编译和执行该程序。

命令

\>scalac Demo.scala
\>scala Demo

输出

10
10 is bigger two times than 5