Scala中的提取器是一个对象,它有一个名为 unapply 的方法作为其成员之一.这种不适用方法的目的是匹配一个值并将其拆分.通常,提取器对象还为构建值定义了双重方法 apply ,但这不是必需的.
让我们举一个对象的例子来定义 apply 和 unapply 方法. apply方法具有与以往相同的含义:它将Test转换为可以应用于括号中的参数的对象,方法与应用方法相同.所以你可以编写Test("Zara","gmail.com")来构造字符串"Zara@gmail.com".
unapply 方法是是什么将Test类变成了提取器,它颠倒了 apply 的构建过程.如果apply需要两个字符串并形成一个电子邮件地址字符串,则unapply会接收一个电子邮件地址并返回两个字符串: user 和 domain .
unapply 还必须处理给定字符串不是电子邮件地址的情况.这就是为什么unapply在字符串对上返回Option类型的原因.如果字符串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 该实例上的方法.我们可以在对象和类中定义应用.
如上所述, unapply 方法的目的是提取我们正在寻找的特定值.它执行相反的操作 apply .使用匹配语句比较提取器对象时,将自动执行 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 }
将上述程序保存在演示中.阶的.以下命令用于编译和执行该程序.
\>scalac Demo.scala \>scala Demo
10 10 is bigger two times than 5
大两倍