scala的提取器(Extractor)
在定义scala类的时候,如果额外自定义了unapply()方法,那么该类的对象就是一个提取器,我们就能从该对象中获取到构造该对象的值有哪些。
先来看一下没有定义unapply()方法的普通类——
(1)scala中普通类class
普通类需要通过new 操作来创建对象,每new 一个实例就创建一个全新的对象。
// 定义一个普通类
scala> class People(name:String, age:Int, city:String)
defined class People
// 通过new 操作来创建对象
scala> val cindy1 = new People("Cindy", 24, "Los Angeles")
cindy1: People = People@29394966
// cindy1和cindy2是两个不同的对象
scala> val cindy2 = new People("Cindy", 24, "Los Angeles")
cindy2: People = People@2c70a1de
再来看看定义了unapply()方法的类——
(2)携带提取器(Extractor)的类class
提取器:是一个带有unapply()方法的实例(对象)。
当我们对提取器对象使用match语句时, 会自动调用unapply()方法。
我们有时候需要使用提取器,以便从一个类的实例中获取:构造该实例的值有哪些。那么,只要把对象传递给unapply()方法,此方法就会从中提取出构造该对象的参数值。示例如下
object Customer {
//编译器在实例化的时候,会自动调用 apply()方法
def apply(name: String, age: Int, item: String):String = {
name + "," + age + "," + item
}
/* unapply()方法是apply()的反向操作
* 把对象传递给unapply()方法,此方法就会从中取出构造该对象的参数值。
*/
def unapply(arg: String): Option[(String, Int, String)] = {
val args_list = arg.split(",")
if (args_list.length == 3) {
Some((args_list(0), args_list(1).toInt, args_list(2)))
}
else None
}
def main(args: Array[String]) {
//使用 apply() 方法则无需使用new 操作就能创建实例
val obj1 = apply("Buddy", 32,"Beer")
println("自动调用apply(),结果:\t" + obj1)
println("调用unapply(),得到构造此对象的参数值列表:\t" + unapply(obj1))
println("调用unapply():\t" + unapply("Goodman"))
//编译器在实例化的时候,会自动调用 apply()方法
val obj2 = Customer("Tony", 27,"Milk")
println("编译器在实例化时自动调用apply(),结果: "+obj2)
//对提取器对象 obj2 使用match语句,则自动调用unapply()
obj2 match {
case Customer(str) => printf("构造出对象 %s 的参数有: %s",obj2,str)
case _ => println("nothing")
}
}
}
【运行 Customer 的输出结果】
自动调用apply(),结果:Buddy,32,Beer
调用unapply(),得到构造此对象的参数值列表:Some((Buddy,32,Beer))
调用unapply(): None
编译器在实例化时自动调用apply(),结果: Tony,27,Milk
构造出对象 Tony,27,Milk 的参数有: (Tony,27,Milk)
最后来看一下无需手动定义unapply()的样例类——
(3)样例类 case class
不同于普通类class ,样例类内置了apply和unapply方法,创建对象时不需要new。
通过样例类,我们可以直接通过实例调用unapply()方法获取构造该实例的值。
scala> case class User(name:String, age:Int, city:String)
defined class User
scala> User.
apply curried toString tupled unapply
// 通过 apply 方法, 无需使用 new 操作就能创建对象
scala> val tony = User.apply("tony", 27, "Peking")
tony: User = User(tony,27,Peking)
//查看由哪些值构造了此对象
scala> User.unapply(tony)
res5: Option[(String, Int, String)] = Some((tony,27,Peking))