话说模式匹配(8) 一个抽取器的例子

一个抽取器的例子

目前List的序列模式(sequence pattern)可以支持对前边若干元素的匹配,比如:List(1,2,3,_*),如果想要实现 List(_*, lastEle) 这样的形式,就需要通过自定义一个抽取器来实现了

// 自定义Extractor
object Append {
    // 接受List结构
    def unapply[A] (l: List[A]) = {
        // 返回Tuple2:前边的若干元素和最后一个元素
        Some( (l.init, l.last) )
    }
}

抽取器里的unapply方法,入参对应你想要进行匹配的对象,出参则是解构后的元素。
比如 list match { case Append(x,y) => } 里面的list对应unapply的入参,x,y对应unapply方法的出参。

为什么unapply方法的返回结果大多都使用Some包装一下,这其实是unapply方法返回值的一些约束

现在看看上面自定义抽取器的使用例子:

scala> (1 to 9).toList match{ case _ Append 9 => println("OK") }
OK

scala> (1 to 9).toList match{ case x Append 8 Append 9 => println("OK") }
OK

上面使用了中缀写法,也可以写成普通的构造方式,只是看起来没有上面的舒服

scala> (1 to 9).toList match{ case Append(Append(_,8),9) => println("OK") }
OK

另外,如果觉得Append这个名字太啰嗦,抽取器object单例名称也可以用符号表达,比如用”:>“来表示

object :> {
    // unapply ...
}

这样对匹配时的表达显得更简短一些

scala> (1 to 9).toList match{ case x :> 8 :> 9 => println("OK") }
OK

另外,以”:“结尾的符号支持从右到左的操作方式,List的子类就采用了“::”这样的名称,以方便模式匹配(当然也是因为早期的一些函数式语言里,如ML里已经定义了::的形式,scala只是延续而已)。

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/140734.html

(0)
上一篇 2021年9月5日
下一篇 2021年9月5日

相关推荐

发表回复

登录后才能评论