13.8 对象匹配(使用提取器进行模式匹配)
对象匹配,什么才算是匹配呢?,规则如下:
case
中对象的unapply
方法(提取器)返回some
集合则为匹配成功返回
None
集合则为匹配失败
备注:
Some
和None
都是Option
的子类型从
2.11.1
开始, scala 为了性能上的优势, 放松了对unapply
返回的值的类型的限制(不必必须是Option
). 返回的类型只要具有以下方法就可以:def isEmpty: Boolean
返回值:false
用来标记匹配成功,true
匹配失败def get: T
返回值: 表示提取到的值.
其实
Some
和None
均包含上面的两个方法.另外一种情况: 如果
unapply
返回一个Boolean
值, 则只表示匹配成功或者失败. 如果是true
则表示匹配成功, 但是不会提取到任意的值.不过, 大部分情况下, 我们还是把要提取的数据封装到
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))
}
执行流程说明:
在
case
匹配的过程中, 如果碰到这种(伴生对象(参数)
)的形式的时, 就会调用这个伴生对象的unapply
方法, 来提前对象.调用
unapply
的时候, 会把前面的匹配表达式(本例中的num
)传递给unapply
如果
unapply
返回的是Some
, 则表示匹配成功. 并unapply
的返回值赋值给伴生对象(参数)
中的参数(本例中的z
),z
其实就是提取到的对象如果
unapply
返回的None
, 则表示匹配失败.继续下一个
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
}
}
执行过程说明:
case Names(one, two, three)
, 这里有 3 个需要提取的结果, 所以会调用伴生对象.unapplySeq
方法.如果这个方法返回的是
Some
, 并且Some
中的序列有 3 个值, 则匹配成功. 否则就匹配失败.