`

scala day6

阅读更多
11. case classes 以及模式匹配
11.1 case class
a:在class 前面加上case ,该class 就成为了case class
b:scala 编译器 首先为 这个类添加了一个工厂方法 用来 构造对象 ,
  这样允许 用户 不用使用new 就能构造对象
  例如:
 case class Var(name: String)
  scala> val v = Var("x")
v: Var = Var(x)


c:在参数列表中的所有参数都隐含为val,因此 这些参数可以作为 字段加以维护
d:编译器为默认该类添加toString,hashcode equals 方法
e: 编译器为 该类 添加一个copy 方法,返回一个可以修改的copy 对象

11.2 pattern matching 模式匹配
a:定义模式匹配函数
selector match { alternatives }
  每个alternatives 都是以case 开始
   每个alternatives 都包含 模式 以及表达式,,其中=> 将表达式和模式给分离出来
 
 
b:例如:

 def simplifyTop(expr: Expr): Expr = expr match {
case UnOp("-", UnOp("-", e))
=> e
// Double negation
case BinOp("+", e, Number(0)) => e // Adding zero
case BinOp("*", e, Number(1)) => e // Multiplying by one
case _ => expr 
}


c:  1.在scala 中match 是一个表达式
    2.在scala 中匹配一个pattern ,执行相关的expression,
       但是不会执行到 下一个case
    3.如果不能匹配到任何一个模式,则会抛出 MatchError 异常
    4. 因此 需要为case 定义一个默认 default case ,该case 什么也不处理
例如:
  expr match {
case BinOp(op, left, right) =>
println(expr +" is a binary operation")
case _ =>
}


11.3 各种模式
a:_ 通配符匹配任何对象
b:constants pattern 常量模式:
  使用常量值作为模式串,例如:
def describe(x: Any) = x match {
case 5 => "five"
case true => "truth"
case "hello" => "hi!"
case Nil => "the empty list"
case _ => "something else"
}


 
c:variable pattern 变量模式
1.变量模式 就像通配符_一样,匹配任何对象
2.和同配符_不一样的是,变量和任何对象绑定在一起 ,你可以使用这些变量就像object 一样
  例如:
 expr match {
case 0 => "zero"
case somethingElse => "not zero: "+ somethingElse
}


d:构造对象模式
  对象模式支持 多层的对象构造,也就是 deep  match,例如:
 expr match {
case BinOp("+", e, Number(0)) => println("a deep match")
case _ =>
}


e:sequence 模式
  1.匹配List 或者Array 这样的顺序类型
  2.使用相同的case 语法,但是可以指定模式了的元素个数,

例如:

expr match {
case List(0, _, _) => println("found it")
case _ =>
}
匹配列表中的前三个元素

3.使用_* 匹配任何长度的元素 ,例如:
 expr match {
case List(0, _*) => println("found it")
case _ =>
}

与list 中的第0个元素匹配,而不管这个List 有多长


e:Tuple pattern

例如:
 def tupleDemo(expr: Any) =
expr match {
case (a, b, c)
=>
println("matched "+ a + b + c)
case _ =>
}

scala> tupleDemo(("a ", 3, "-tuple"))
matched a 3-tuple


f:Typed Pattern
1.方便做类型测试和类型转换
2.Map[_, _] 类型 在运行时,内部的类型会被同一转成 Object , 因此会碰到类型擦除的问题
3.但是Array[String] Array[Int]由于 在运行其使用的的底层机制是 String[] 或者int[] 类型,因此不会出现类型擦除的问题

例如:
 def generalSize(x: Any) = x match {
case s: String => s.length
case m: Map[_, _] => m.size
case _ => -1
}


def isIntIntMap(x: Any) = x match {
case m: Map[Int, Int] => true
case _ => false
}
scala> isIntIntMap(Map(1 -> 1))
res19: Boolean = true
scala> isIntIntMap(Map("abc" -> "abc"))
res20: Boolean = true


scala> def isStringArray(x: Any) = x match {
case a: Array[String] => "yes"
case _ => "no"
}
isStringArray: (x: Any)java.lang.String
scala> val as = Array("abc")
as: Array[java.lang.String] = Array(abc)
scala> isStringArray(as)
res21: java.lang.String = yes
scala> val ai = Array(1, 2, 3)
ai: Array[Int] = Array(1, 2, 3)
scala> isStringArray(ai)
res22: java.lang.String = no


f.绑定变量
1. 变量名e+ 符号@+pattern 的形式,
pattern 完成普通的模式匹配,如果匹配成功,则将 被匹配的对象赋值给指定的变量
例如:
 expr match {
case UnOp("abs", e @ UnOp("abs", _)) => e
case _ =>
}


11.4 模式中的条件表达式
a: 在模式中 一个变量只允许出现一次
b:可以在模式中添加if 条件表达式 进行判断
例如:
def simplifyAdd(e: Expr) = e match {
case BinOp("+", x, y) if x == y =>
BinOp("*", x, Number(2))
case _ => e
}


// match only positive integers
case n: Int if 0 < n => ...
// match only strings starting with the letter ‘a’
case s: String if s(0) == 'a' => .


11.5 pattern overlap 模式交叠
a:pattern 是根据他们写的顺序 进行匹配的。例如:
 def simplifyAll(expr: Expr): Expr = expr match {
case UnOp("-", UnOp("-", e)) =>
simplifyAll(e)
// ‘-’ is its own inverse
case BinOp("+", e, Number(0)) =>
simplifyAll(e)
// ‘0’ is a neutral element for ‘+’
case BinOp("*", e, Number(1)) =>
simplifyAll(e)
// ‘1’ is a neutral element for ‘*’
case UnOp(op, e) =>
UnOp(op, simplifyAll(e))
case BinOp(op, l, r) =>
BinOp(op, simplifyAll(l), simplifyAll(r))
case _ => expr
}


b:如果编译器检查到 之前的模式已经将所有的模式覆盖了,那么在这个模式之后定义的模式会被标注为unreachable code

11.6 sealed classes
a:为了得到编译器的帮助。列出所欲的模式组合,需要将case class 的父类定义为 sealed
b:加了sealed 关键字的class 除了那些在同一个文件中的子类外不允许添加任何子类
c:如果打算写一些用于模式匹配的类,应该考虑用sealed 封装 这些类的父类
例如:
sealed abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String,
left: Expr, right: Expr) extends Expr


d:使用unchecked annotation 来避免编译器检查各种模式的组合,避免编译器发出这种警告,“ 表达式:@unchecked”例如


def describe(e: Expr): String = (e: @unchecked) match {
case Number(_) => "a number"
case Var(_)
=> "a variable"
}


11.7 Option 类型
a:scala 为Option value 提供Option 类型,如果真实的值存在 则返回真实的值,否则返回None object

例如:
cala> val capitals =
Map("France" -> "Paris", "Japan" -> "Tokyo")
capitals: scala.collection.immutable.Map[java.lang.String,
java.lang.String] = Map(France -> Paris, Japan -> Tokyo)

scala> capitals get "France"
res23: Option[java.lang.String] = Some(Paris)
scala> capitals get "North Pole"
res24: Option[java.lang.String] = None

scala> def show(x: Option[String]) = x match {
case Some(s) => s
case None => "?"
}
show: (x: Option[String])String
scala> show(capitals get "Japan")
res25: String = Tokyo
scala> show(capitals get "France")
res26: String = Paris
scala> show(capitals get "North Pole")
res27: String = ?


11.8 pattern every

1. 在变量定义中的模式 ,例如 在一个赋值中生成多个变量
 scala> val myTuple = (123, "abc")
myTuple: (Int, java.lang.String) = (123,abc)
scala> val (number, string) = myTuple
number: Int = 123
string: java.lang.String = abc


2.在function 中的case squence,  为构造一个函数提供多个入口,见 Function1
例如:
 val withDefault: Option[Int] => Int = {
case Some(x) => x
case None => 0
}


scala> withDefault(Some(10))
res28: Int = 10
scala> withDefault(None)
res29: Int = 0


上述定义其实是 生成一个Function1 类

3.对于下面这种额外的情况: 在使用函数之前要先判断 输入的参数是否满足条件,如果满足,则该函数能够返回正确的值,否则则会抛出异常。对于这样的函数 外面可以定义为 :Parial Function
例如:
new PartialFunction[List[Int], Int] {
def apply(xs: List[Int]) = xs match {
case x :: y :: _ => y
}
def isDefinedAt(xs: List[Int]) = xs match {
case x :: y :: _ => true
case _ => false
}


4.例如:

val second: List[Int] => Int = {
case x :: y :: _ => y
}


second 函数对于list 中的元素<2 时,则会抛出异常。为了避免这种情况,可以将second 定义为Parital Function .

val second: PartialFunction[List[Int],Int] = {
case x :: y :: _ => y
}


那么在使用这个函数前就可以先用second.isDefinedAt 这个方法先判断是否满足条件,如果满足,之后在调用该函数


5. 表达式中的模式
例如 :
scala> for ((country, city) <- capitals)
println("The capital of "+ country +" is "+ city)
The capital of France is Paris
The capital of Japan is Tokyo

scala> val results = List(Some("apple"), None,
Some("orange"))
results: List[Option[java.lang.String]] = List(Some(apple),
None, Some(orange))
scala> for (Some(fruit) <- results) println(fruit)
apple
orang


将集合内的元素展开,如果符合指定的模式,则输出,否则 不输出


12.Tuple 元组类型的构造和析构




 
 





























 


 


 


  
 



   
分享到:
评论

相关推荐

    Scala_day01_scala_

    scala学习笔记,适合初学scala的人使用,通俗易懂,小案例适合练手

    Scala.Functional.Programming.Patterns.178398

    Solve day-to-day programming problems using functional programming idioms Cut down the boiler-plate and express patterns simply and elegantly using Scala's concise syntax Tame system complexity by ...

    Programming-in-Scala-2nd.pdf

    day. You won’t understand the zen of objects being functions and functions being objects in your first week. Each feature of the language is another light bulb waiting to switch on over your head. I...

    scala-1-day:一天之内的Scala。 向真正使用它的人学习

    一天之内的Scala ...然后你需要克隆 repo git clone https://github.com/gilt/scala-1-day.git 。 之后你应该可以去 000.setup 并运行sbt "run-main javax.HelloWorld"和sbt "run-main scalax.HelloWorld" 。

    scala工具库utils4s.zip

    utils4s包含各种scala通用、好玩的工具库demo和使用文档,通过简单的代码演示和操作文档,各种库信手拈来。时间操作的示例代码:package cn.thinkjoy.utils4s.lamma import io.lamma._ /**  * test  *  */ ...

    WarszawScala-slick-day:华沙 Scala 用户组聚会的项目框架

    华沙Scala光滑的一天 华沙 Scala 用户组聚会的项目框架。 通过更改application.conf文件中的设置,可以将应用程序配置为与数据库和服务的模拟实现一起运行。 建议在 sbt 中使用re-start命令运行应用程序并使用re-...

    KafkaSparkCassandraDemo:Cassandra Day Dallas演示

    #Dallas Cassandra Day KafkaSparkCasandraDemo 为了运行此演示,假定您已安装以下组件,并且在本地系统上可用。 Datastax企业版4.8 Apache Kafka 0.8.2.2,我使用了Scala 2.10构建吉特sbt ## Kafka入门请使用以下...

    matlab导入excel代码-utl_standard_deviation_of_90_day_rolling_standard_devia

    Scala Perl CC#Excel MS Access JSON图形映射NLP自然语言处理机器学习igraph DOSUBL DOW循环stackoverflow SAS社区。 90天滚动标准偏差的标准偏差 WPS/Proc R 10 million readings is a tiny amount of data. Are ...

    python100Day

    Python - 100天从新手到大师 ...数据分析挖掘 - Python / R / Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开

    Reactive Design Patterns

    Software engineers and architects will learn patterns that address day-to-day distributed development problems in a fault-tolerant and scalable way. Project leaders and CTOs will gain a deeper ...

    典型相关分析matlab实现代码-Python_100_Day:Python_100_Day

    Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师 Python自动化运维工程师 Python数据分析 / 数据...

    movies_ratings:NewDay的数据工程师招聘流程

    movie_ratings NewDay的数据工程师招聘流程

    Mastering Apache Spark 2.x - Second Edition

    You will learn to use Spark as a big data operating system, understand how to implement advanced analytics on the new APIs, and explore how easy it is to use Spark in day-to-day tasks. Style and ...

    典型相关分析matlab实现代码-Python-100Day:python-100天

    Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师 Python自动化运维工程师 Python数据分析 / 数据...

    贝岭的matlab的代码-fpday:FPDayUnconference的存储库

    Day Benelux 会议使用复杂的反馈和选择系统),以避免令人不快的“放开我的伙伴”效应。 这并不妨碍我们能够邀请一两个著名的演讲者,我们知道他们总是有有趣的事情要讲,并且谁将成为出色的头条新闻...... 底端 ...

    典型相关分析matlab实现代码-python-100-day:python-100天

    Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师 Python自动化运维工程师 Python数据分析 / 数据...

    matlab导入excel代码-python_100day_bible:自学python100天,入门到高手宝典

    Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师 Python自动化运维工程师 Python数据分析 / 数据...

    worldwindjava源码-every-day-read-watch:我发现有趣的文章、视频或播客的(半)每日摘要

    Kotlin、Kafka、Scala、Java、大数据工程、DDD 和吉他/音乐/音频的内容。 :nerd_face: 注意:当然,这是我主要在下班时阅读的内容。 :see-no-evil_monkey: 我目前的技术栈@工作是 Kotlin、Java、Kafka、Spring、...

    Mastering Functional Programming

    Learn how functional programming can help you in deploying web servers and working with databases in a declarative and pure way ... Use functional data structures and collections in your day-to-day work

    ConferenceTrackManagement.zip

    You are planning a big programming conference and have receivedmany proposals which have passed the initial screen process but you're havingtrouble fitting them into the time constraints of the day --...

Global site tag (gtag.js) - Google Analytics