13.8 对象匹配(使用提取器进行模式匹配)

对象匹配,什么才算是匹配呢?,规则如下:

  1. case中对象的unapply方法(提取器)返回some集合则为匹配成功

  2. 返回None集合则为匹配失败

备注:

  1. SomeNone 都是Option的子类型

  2. 2.11.1 开始, scala 为了性能上的优势, 放松了对unapply返回的值的类型的限制(不必必须是 Option). 返回的类型只要具有以下方法就可以:

    • def isEmpty: Boolean
      返回值: false用来标记匹配成功, true匹配失败

    • def get: T 返回值: 表示提取到的值.

  3. 其实SomeNone 均包含上面的两个方法.

  4. 另外一种情况: 如果unapply返回一个Boolean值, 则只表示匹配成功或者失败. 如果是 true则表示匹配成功, 但是不会提取到任意的值.

  5. 不过, 大部分情况下, 我们还是把要提取的数据封装到Some中返回.

1. 对象提取流程快速理解(提取单个对象)

package com.atguigu.day11.moshipipei

object ObjMatch {
  def main(args: Array[String]): Unit = {
    val num: Double = 9.0
    num match {
      case Square(z) => println("z = " + z)
      case _ => println("啥也没有匹配到")
    }

  }
}

object Square {
  def apply(a: Double): Double = a * a

  def unapply(arg: Double): Option[Double] = Some(math.sqrt(arg))
}

执行流程说明:

  1. case匹配的过程中, 如果碰到这种(伴生对象(参数))的形式的时, 就会调用这个伴生对象的unapply方法, 来提前对象.

  2. 调用unapply的时候, 会把前面的匹配表达式(本例中的num)传递给unapply

  3. 如果unapply返回的是Some, 则表示匹配成功. 并unapply的返回值赋值给伴生对象(参数) 中的参数(本例中的z), z其实就是提取到的对象

  4. 如果unapply返回的None, 则表示匹配失败.

  5. 继续下一个case的匹配...


2. 提取序列

unapply只能提取单个对象, 如果想提取多个对象(序列), 需要提取方法unapplySeq

package com.atguigu.day11.moshipipei

object ObjMatch2 {
  def main(args: Array[String]): Unit = {
    val s = "lisi,zhangsan,wangwu"
    val res = s match {
      case Names(one, two, three) => s"成功! one=$one, two=$two, three=$three"
      case _ => "匹配失败"
    }
    println(res)
  }
}

object Names {

  def unapplySeq(str: String) = {
    if (str.contains(","))
      Some(str.split(","))
    else
      None
  }
}

执行过程说明:

  1. case Names(one, two, three), 这里有 3 个需要提取的结果, 所以会调用伴生对象.unapplySeq方法.

  2. 如果这个方法返回的是Some, 并且 Some中的序列有 3 个值, 则匹配成功. 否则就匹配失败.

Copyright © 尚硅谷大数据 2019 all right reserved,powered by Gitbook
该文件最后修订时间: 2019-03-01 13:03:34

results matching ""

    No results matching ""