模式匹配(7) case类的匹配

前一个文章中的guard 在case子句中加上自己的逻辑。是match的语法。 和前面的case 匹配的类型,或者匹配的某一定规则的泛式不可混为一谈。(吃了亏要谨记)

言归正传,接着说case类的匹配。

在第二篇中scala怎么实现模式匹配中说到,case class 类型自带unapply 方法,用于解构对象。或者我们自定义的提取器,定义一个unapply 方法,用于提取和解构。

其实所有的unapply 方法都返回Option[TupleN[...]],这个地方的N表示可以从对象中提取的值的个数。

因为unapply方法可以“否决”这个匹配,这时方法返回就为None。这个时候scala会使用下一个case 子句。

在第4篇中我截取了+: 类型实现提取的源码 。

其中unapply方法如下:

def unapply[T,Coll](collect: Coll) :Option[(T,coll)]

头部的类型被推断为T,尾部被推断为某种集合类型。Coll同时也是输入参数的类型。 所以我们可以看到,返回的Option 其实即是 输入参数的头部的提取,和尾部组成的两个元素元祖。

对于seq序列,希望提取时返回非固定数量的元素,seq 提供了 unapplySeq 方法实现,源码如下


注释中我们可以看到, 这个方法就是在模式匹配的时候被调用。

这个方法接受一个集合类型参数,返回此集合类型参数的Option对象。对于在和中场景中会使用到呢?如下:


在模式匹配Seq(head,head2,_*) 的时候,其实是去调用了seq的unapplySeq 方法,提取其中的部分;

以上是scala 自带的unapply 和unapplySeq 方法在模式匹配中用于提取或者结构的相应作用。

对于自定义的case class 中自定义的可变参数的提取模式的匹配有如下用法:


其中反编译scalac 自动生成的代码发现,


哈哈哈 也是去实现的unapplySeq方法。。