模式匹配,什么才算是匹配呢?即,case中unapply方法返回some集合则为匹配成功,返回none集合则为匹配失败。下面我们来看几个例子做详细探讨。
所谓提取器,就是一个带有unapply 方法的对象。我们可以把unapply方法当做伴生对象中apply方法的方向操作,apply方法接受构造参数,然后将它们变成对象,而unapply方法接受一个对象,然后从中提取值,通常这些值就是当初用来构造该对象的值
1、unapply
apply
Map("Alex" -> 10)
unapply
map("Alex")
数据的封装使用apply,数据的解封使用unapply
--调用unapply,传入number
--接收返回值并判断返回值是None,还是Some
--如果是Some,则将其解开,并将其中的值赋值给n(就是case Square(n)中的n)
//创建object Square:
object Square {
def unapply(arg: Double): Option[Double] = Some(math.sqrt(arg))
}
//模式匹配使用
val number: Double = 36.0
number match {
//case 匹配过程中 默认调用unapply 自动调用</pre>
case Square(n) => println(s"square ro ot of $number is $n")
case _ => println("nothing matched")
}
2、unapplySeq
要提取任意长度的值的序列,我们应该用unapplySeq来命名我们的方法。它返回一个Option[Seq[A]],其中A是被提取的值的类型,举例来说,Name提取器可以产出名字中所有组成部分的序列
--调用unapplySeq,传入namesString
--接收返回值并判断返回值是None,还是Some
--如果是Some,则将其解开
--判断解开之后得到的sequence中的元素的个数是否是三个
--如果是三个,则把三个元素分别取出,赋值给first,second和third
//创建object Names
object Names {
def unapplySeq(str: String): Option[Seq[String]] = {
if (str.trim.contains(",")){
Some(str.split(","))
}else{
None
}
}
}
//模式匹配使用
val str: String = "Alex,Bob,Kotlin"
str match {
case Names(x, y, z) => println(x + "," + y + "," + z)
}
val namesString = "Alice,Bob,Thomas"
namesString match {
case Names(first, second, third) => {
println("the string contains three people's names")
println(s"$first $second $third")
}
case Names(x, y, z, d) => println(x + "-" + y + "-" + z + "-" + d)
case Names(x, y, _*) => println(x + "-" + y)
case _ => println("nothing matched")
}
(1)调用unapplySeq,传入namesString
(2)接收返回值并判断返回值是None,还是Some
(3)如果是Some,则将其解开
(4)判断解开之后得到的sequence中的元素的个数是否是三个
(5)如果是三个,则把三个元素分别取出,赋值给first,second和third
如果没有unapplySeq方法和pattern match语法之间的这种结合,我们自己写代码来做这五件事会显得很是繁琐。尖叫提示:不要同时提供相同入参类型的unapply和unapplySeq方法
转载于:https://www.jianshu.com/p/28f6b04bf78e