Scala笔记

提取器 模式匹配

提取器效果与构造器相反:构造器从给定的参宿列表创建一个对象,而提取器却是从传递给它的对象中提取出构造该对象的参数

样例类

scala自动为样例类创建一个伴生对象:一个包含了applyunappley方法的单例对象
apply方法用来创建样例类的实例,unapply需要被伴生对象实现,以使其成为提取器

第一个提取器

trait User {
  def name:String
}
class FreeUser(val name:String) extends User
class PremiumUser(val name:String) extends User

object 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 User

object 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提供了提取任意多个参数的模式匹配方法
接受某一类型的对象,将其解构成列表

提取给定的名字

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()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容