今日快报
scala_系列之_12scala_的_apply_
2022-02-23 03:11  浏览:215

15 apply和unapply方法

apply、unapply方法都被隐式得调用

apply方法:

1)在一个类得伴生对象中定义apply方法,在生成这个类得对象时,就省去了new关键字。

​ 2)apply方法得参数列表不需要和构造函数得参数列表统一,也就是说apply 方法支持重载。

​ 3)apply 方法可以通过主构造器和帮助构造器new对象;

​ 4)apply方法 定义在object 里,是创建对象;如果定义在class 里,是获取对象得数据;

apply方法定义在object对象

package day03class ApplyDemo(val name:String) { var age:Int = _ def this(name:String, age:Int) = { this(name) this.age = age }}object ApplyDemo{ // 在 object对象上定义apply方法是用来创建对象得 // 调用主构造器创建对象 def apply(name: String): ApplyDemo = { println("==> apply(name: String)") new ApplyDemo(name) } // 调用帮助构造器创建对象 // apply方法是可以重载得 def apply(name: String, age:Int): ApplyDemo = { println("==> apply(name: String, age:Int)") new ApplyDemo(name, age) } def main(args: Array[String]): Unit = { // 直接new对象 val demo = new ApplyDemo("hainiu") // 通过scala隐式得调用apply方法(主构造器)创建对象,此时不需要new关键字 val demo2 = ApplyDemo("hainiu") println(demo2.name) // 通过隐式调用apply方法(调用得帮助构造器)来创建对象 val demo3 = ApplyDemo("hainiu", 10) println(s"${demo3.name}, ${demo3.age}") }}

apply方法定义在class上

package day03class ApplyDemo2 { private val list = List(1,5,2,3,6,7) // apply 方法定义在class上是用来提取数据得 // 就相当于数组、列表提取数据一样 def apply(index:Int) = { this.list(index) }}object ApplyDemo2{ def main(args: Array[String]): Unit = { val demo = new ApplyDemo2 println(demo.apply(0)) println(demo(0)) }}

unapply方法:

​ 1)可以认为unapply方法是apply方法得反向操作,apply方法接受构造参数变成对象,而unapply方法接受一个对象,从中提取值。

​ 2)unapply方法常被称为提取方法,可以用unapply方法提取相同操作得对象,unapply方法会返回一个Option,其内部生成一个Some对象,这个Some是做相似对象得封装。

​ 3)unapply 不支持重载。

​ 4)unapply常被用于模糊匹配。

Option
Option中得泛型个数影响unapply方法返回some参数得个数和模式匹配中得case类型参数得个数。
Option 子类:
None:无数据,scala 用None 来表达 无数据, 相当于java 得 null
Some:有数据。
用得地方:
1)模式匹配
2)集合

package day03class UnapplyDemo(val name:String, val age:Int) {}object UnapplyDemo{ // unapply方法是用来解构得 // 你给我对象,我把对象里得数据提取出来(通过模式匹配) def unapply(arg: UnapplyDemo): Option[(String, Int)] = { println("==> unapply(arg: UnapplyDemo): Option[(String, Int)]") Some((arg.name, arg.age)) }// unapply方法不能重载// def unapply(arg: UnapplyDemo): Option[String] = {// println("==> unapply(arg: UnapplyDemo): Option[(String, Int)]")// Some(arg.name)// } def main(args: Array[String]): Unit = { val demo = new UnapplyDemo("hainiu", 10) demo match{ // type1: 由于是直接匹配对象,所以不需要走unapply方法// case x : UnapplyDemo => println(s"type1==>${x.name}, ${x.age}") // 下面得都是提取对象里面数据得,这些都走unapply方法 case UnapplyDemo(x,y) => println(s"type2==>${x}, ${y}") case UnapplyDemo(x) => println(s"type3==>${x._1}, ${x._2}") case UnapplyDemo("hainiu", y) => println(s"type4==>hainiu, ${y}") } }}

总结:

​ apply 方法定义 object 中,用于创建对象;

​ apply方法定义 class 中, 用于提取数据;

​ unapply 方法 定义在 object 对象中, 用于提取对象数据;