Chinaunix首页 | 论坛 | 博客
  • 博客访问: 371508
  • 博文数量: 85
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 657
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-17 20:48
个人简介

行到水穷处,坐看云起时

文章分类

全部博文(85)

文章存档

2019年(2)

2018年(1)

2016年(1)

2015年(66)

2014年(15)

我的朋友

分类: Java

2015-05-27 15:30:25

Scala中,extractors(提取器)是一个object,功能和case class类似,用来匹配特定的模式。
Extractor中,都会包含一个unapply方法,用于匹配特定值并将其进行拆分成多个属性;同时可以包含apply方法(可选),用于从多个属性构造出特定的值。比如:

scala> object Email{
     |  def apply(user:String,domain:String) = user + "@" + domain
     |  def unapply(mail:String) : Option[(String,String)] = {
     |    val arr = mail.split("@")
     |    if(arr.length == 2) Some(arr(0),arr(1)) else None
     | }
     | }
defined object Email

scala> Email("dreamer","host")
res0: String = dreamer@host

scala> val mailAddr = "alice@dreamhost"
mailAddr: String = alice@dreamhost

scala> mailAddr match {
     |  case Email(user,domain) => println(user + "'s email address")
     |  case _ => println("Not a valid email address")
     | }
alice's email address

Email中,由于unapply方法的参数不一定都符合邮件格式,所以返回值类型为Option,匹配的时候返回Some,不匹配的时候返回None。Scala中,object名后直接跟小括号会调用object的apply方法,不过在match表达式中,调用的是extractor的unapply方法。

对于提取固定属性参数,上面的定义可以应付,不过,如果要处理变长属性参数,上面的定义方式就无能为力了。为了让extractor就能处理变长属性参数,需要将unapply方法替换为unapplySeq,同时将返回值类型改为Option[Seq[T]]即可。示例如下:

scala> object PathResolver {
     |  def apply(dirs:String*) = dirs.mkString("/")
     |  def unapplySeq(dir:String):Option[Seq[String]] = Some(dir.split("/"))
     | }
defined object PathResolver

scala> PathResolver("","usr","local","lib")
res7: String = /usr/local/lib

scala> def isInUserDir(dir:String) = {
     |  dir match {
     |   case PathResolver("","usr",_*) => true
     |   case _ => false
     |  }
     | }
isInUserDir: (dir: String)Boolean

scala> isInUserDir("/usr/local")
res8: Boolean = true

scala> isInUserDir("/root")
res9: Boolean = false

参考自:Programming Scala 2nd Edition
阅读(1159) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~