6. Scala中的apply、update、unapply、unapplySeq

1. apply

apply方法经常被用在伴生对象中,用来构造对象而不用显式地使用new。例如以下用 Student("zs", 11, "beijing")构造对象。

2. update

在class中创建,在object中创建无用。作用如下:

val arr = Array(1, 3, 4)
arr(2) = 5  // 相当于调用了 arr.update(2, 5)
println(arr.mkString(","))  // 1,3,5
3. unapply

在object中才起作用。
apply方法接受构造参数,然后将它们变成对象。而unapply方法接受一个对象,然后从中提取值,通常这些值就是当初用来构造该对象的值。

4. unapplySeq

提取任意长度的值的序列,返回一个 Option[Seq[A]],其中A是被提取的值的类型。
同一个object中同时有unapply方法和unapplySeq方法时会调用unapply方法,如果参数条件符合unapplySeq但是不符合unapply方法也会报错

object ApplyTest {
  def main(args: Array[String]): Unit = {
    // 默认调用了Object中的apply方法
    val stu01 = Student("zs", 11, "beijing")
    // 调用的是class里的构造方法
    val stu02 = new Student("ls", 20, "shanghai")
    // 默认调用了 update方法,右边的 "beijing" 是update的第三个参数
    Student("zs", 11) = "beijing"  // changing address of zs, whose age is 11 to beijing.
    stu02("ls", 11) = "shanghai"   // changing address of ls, whose age is 11 to shanghai.
    // 相当于调用了 unapply 方法
    val Student(name, age, address) = stu01
    println(s"$name $age $address")
    // 相当于调用了 unapplySeq 方法
    val Name(first, second) = "Bob White"
    println(s"$first $second")

    val n = new Name02()
    val n(f, s) = "Bob White"
    println(s"$f $s")
  }
}
class Student (val name:String, val age:Int, val address:String) {
  def getAddress(): String = {
    this.address
  }
  def read(book:String): Unit = {
    println(name + " is reading a book named " + book)
  }
  def update(name: String, age: Int, address: String) = {
    println(s"changing address of $name, whose age is $age to $address.")
  }

}
object Student {
  def apply(name:String, age:Int, address:String): Student = {
    new Student(name, age, address)
  }
  def update(name: String, age: Int, address: String) = {
    println(s"changing address of $name, whose age is $age to $address.")
  }
  def unapply(stu: Student): Option[(String, Int, String)] = {
    if (stu == null)
      None
    else
      Some((stu.name, stu.age, stu.address))
  }
}
object Name {
  def unapplySeq(arg: String): Option[Seq[String]] = {
    val infoArr = arg.split(" ")
    if (infoArr.size == 0)
      None
    else
      Some(arg.split(" "))
  }
}

class Name02 {
  def unapplySeq(arg: String): Option[Seq[String]] = {
    val infoArr = arg.split(" ")
    if (infoArr.size == 0)
      None
    else
      Some(infoArr)
  }
}

猜你喜欢

转载自blog.csdn.net/qq_42994084/article/details/105338203