黑猴子的家:Scala 提取器

模式匹配,什么才算是匹配呢?即,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

猜你喜欢

转载自blog.csdn.net/weixin_34204057/article/details/91182455