提取器是从传递给它的对象中提取出构造该对象的参数。
Scala 标准库包含了一些预定义的提取器,我们会大致的了解一下它们。
Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。
//注解可以理解为函数或者是对象,是由编译器展开
//@volatile
//@trasient
//@varargs
//@throws
@Dtcoder(name="scala", salary = 15000) case class Pers(name: String, age: Int)
class Dtcoder(val name: String,val salary:Int) extends annotation.Annotation
object Dtcoder{
def apply(name:String, salary:Int) = {
println("Dtcode apply methods invoked")
new Dtcoder(name, salary)
}
// def unapply(information: String) ={
// Some((information.substring(0, information.indexOf(" ")), information.substring(information.indexOf(" ") + 1)))
// }
def unapply(information: Dtcoder) ={
Some(information.name, information.salary)
}
}
object ExtractorDemo extends App{
val per = Pers.apply("spark", 6) //调用apply工厂构造方法构造出类的实例对象
val Pers(name, age) = per //用UNapply方法将实例per中的name和age提取出来并赋值给pers
println(name + " : "+ age)
per match{
case Pers(name, sge) => println("hi " + name + " ; " + age)
}
// val Dtcoder(dtname, salary) = "spark 10000"
val dtcoder = Dtcoder("spark", 10000)
val Dtcoder(dtname, salary) = dtcoder
}
模式匹配使用提取器:
当一个类的实例后跟括号使用零个或多个参数的列表,所述编译器调用应用的方法在该实例上。我们可以定义同时适用对象和类。
如上述所提到的,unapply方法的目的是提取我们寻找一个特定的值。它相反的操作和apply一样。当比较使用匹配语句中unapply方法的提取对象将被自动执行,如下所示:
object Test {
def main(args: Array[String]) {
val x = Test(5)
println(x)
x match
{
case Test(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
}
让我们编译和运行上面的程序,这将产生以下结果:
C:/>scalac Test.scala
C:/>scala Test
10
10 is bigger two times than 5
C:/>