Scala笔记

提取器 模式匹配 提取器效果与构造器相反:构造器从给定的参宿列表创建一个对象,而提取器却是从传递给它的对象中提取出构造该对象的参数
样例类 scala自动为样例类创建一个伴生对象:一个包含了applyunappley方法的单例对象
apply方法用来创建样例类的实例,unapply需要被伴生对象实现,以使其成为提取器
第一个提取器

trait User { def name:String } class FreeUser(val name:String) extends User class PremiumUser(val name:String) extends Userobject FreeUser { def unapply(user:FreeUser):Option[String] = Some(user, name) } object PremiumUser { def unapply(user:PremiumUser):Option[String] = Some(user, name) }//test code val user:User = new PremiumUser("Daniel") user match { case FreeUser(name) => "Hello, " + name case PremiumUser(name) => "Welcome back, " + name }

提取多个值
trait User { def name:String def score:Int } class FreeUser( val name:String, val score:Int, val upgradeProbability:Double ) extends User class PremiumUser( val name:String, val score:Int ) extends Userobject FreeUser { def unapply(user:FreeUser):Option[(String, Int, Double)] = Some((user.name, user.score, user.upgradeProbability)) } object PremiumUser { def unapply(user:PremiumUser):Option[(String, Int)] = Some((user.name, user.score)) }//test code val user:User = new FreeUser("Daniel", 3000, 0.7d) user match { case FreeUser(name, _, p) => if (p > 0.75) "$name, what can we do for you today?" else "Hello $name" case PremiumUser(name, _) => "Welcome back, dear $name" }

布尔提取器 用于检查是否匹配
object premiumCandidate { def unapply(user:FreeUser):Boolean = user.upgradeProbability > 0.75 }//test code val user:User = new FreeUser("Daniel", 2500, 0.8d) user match { case freeUser @ premiumCandidate() => initiateSpamProgram(freeUser) case _ => sendRegularNewsletter(user) }

  • @操作符
    将提取器匹配成功的实例绑定到一个变量上,该变量有着与提取器所接受的对象相同的类型
中缀表达式
val xs = 58 #:: 43 #:: 93 #:: Stream.empty xs match { case first #:: second #:: _ => first - second case _ => -1 }

  • 结构列表、流的方法与创建方法类似,都使用cons操作符
    cons操作符:::, #::
  • 列表和流的cons操作符一般使用中缀表达式
流提取器
object #:: { def unapply[A](xs: Stream[A]):Option[(A, Stream[A])] = if (xs.isEmpty) None else Some(xs.head, xs.tail) }

使用提取器
  • 使用样例类自动获得可用的提取器
  • 只有当从无法掌控的类型中提取数据,或者是需要其他进行模式匹配的方法时,才需要实现自己的提取器
提取器的一种常见用法是从字符串中提取出有意义的值
序列提取 【Scala笔记】scala提供了提取任意多个参数的模式匹配方法
接受某一类型的对象,将其解构成列表
提取给定的名字
object GivenNames { def unapplySeq(name:String):Option[Seq[String]] = { val names = name.trim.split(" ") if (name.forall(_.isEmpty)) None else Some(names) } }def greetWithFirstName(name:String) = name match { case GivenNames(firstName, _*) => "Good morning, $firstName" case _ => "Welcome! Please make sure to fill in your name" }

固定和可变的参数提取
object Names { def unapplySeq(name:String):Option[(String, String, Seq[String])] = { val names = name.trim.split(" ") if (names.size < 2) None else Some((names.last, names.head, names.drop(1).dropRight(1))) } }def greet(fullName:String) = fullName match { case Names(lastName, firstName, _*) => "Good morning, $firstName $lastName!" case _ => "Welcome! Please make sure to fill in your name" }

无处不在的模式 模式匹配表达式 模式匹配表达式:其返回值是由第一个匹配的模式中的代码块决定的
模式匹配允许解耦两个并不真正属于彼此的东西,使得代码易于测试
值定义中的模式
def gameResult():(String, Int) = ("Daniel", 3500) val result = gameResult() println(result._1 + ":" + result._2)val (name, score) = gameResult() println()

    推荐阅读