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的基础语法与Java类似,但它提供了更简洁的表达...
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 ...然后你需要克隆 repo git clone https://github.com/gilt/scala-1-day.git 。 之后你应该可以去 000.setup 并运行sbt "run-main javax.HelloWorld"和sbt "run-main scalax.HelloWorld" 。
utils4s包含各种scala通用、好玩的工具库demo和使用文档,通过简单的代码演示和操作文档,各种库信手拈来。时间操作的示例代码:package cn.thinkjoy.utils4s.lamma import io.lamma._ /** * test * */ ...
华沙Scala光滑的一天 华沙 Scala 用户组聚会的项目框架。 通过更改application.conf文件中的设置,可以将应用程序配置为与数据库和服务的模拟实现一起运行。 建议在 sbt 中使用re-start命令运行应用程序并使用re-...
Apache Spark 是使用 Scala 编程语言编写的。为了支持 Apache Spark 和 Python 的协作,PySpark 被释放出来,实际上是一个 Python API 用于 Spark。PySpark 是一个 Python API,支持 Python 与 Apache Spark 的集成...
NewDay作为一家可能的公司,其数据工程师的招聘流程通常会涵盖对技术技能,尤其是编程语言如Scala的深入理解的评估。以下是对电影评分数据集和Scala在数据工程中的应用进行详细阐述: Scala是一种多范式编程语言,...
#Dallas Cassandra Day KafkaSparkCasandraDemo 为了运行此演示,假定您已安装以下组件,并且在本地系统上可用。 Datastax企业版4.8 Apache Kafka 0.8.2.2,我使用了Scala 2.10构建吉特sbt ## Kafka入门请使用以下...
在IDEA中编写Spark程序,需要先配置Maven仓库,安装Scala环境,然后创建Maven项目并安装Scala插件。在pom.xml中添加Spark的相关依赖,如`spark-core_2.11`。创建SparkContext时,通过SparkConf设置配置信息,如...
- 如 `src/test/scala/day01/Day01Test.scala` 包含针对Day01问题的单元测试。 3. **input** - 包含每个问题的输入数据,通常为文本文件。 - 文件名可能与问题编号对应,例如 `input/day01.txt`。 4. **output** -...
6. **机器学习和人工智能**:随着大数据与AI的结合日益紧密,Spark的MLlib库提供了丰富的机器学习算法,简化了开发流程,使得数据科学家能够快速构建和训练模型。 【Spark环境搭建与IDEA编写Spark程序】 在本地...
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 ...
Python - 100天从新手到大师 ...数据分析挖掘 - Python / R / Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开
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 ...
6. **Actor模型与Concurrent编程**:虽然AOC 2020的大部分问题并不涉及并发,但Scala的Akka框架提供了Actor模型,允许开发人员以简单而安全的方式处理并发和异步任务。如果某些挑战需要并行计算,可以考虑使用这一...
Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师 Python自动化运维工程师 Python数据分析 / 数据...
1. **日期时间模型**:库可能定义了自己的日期时间模型,如`YearMonthDay`、`LocalTime`等,这些模型可能比Java 8的`java.time`包更加轻量级和易于使用。 2. **解析和格式化**:提供解析字符串到日期时间对象以及将...
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 ...
Scala / Matlab 机器学习 - Python / R / Java / Lisp 作为一名Python开发者,主要的就业领域包括: Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师 Python自动化运维工程师 Python数据分析 / 数据...