章节概述(摘自 序-如何阅读本书)
第1-3章 scala核心语言特性
第4章 模式匹配
第5章 隐式详解
第6章 函数编程
第7章 scala对for循环的扩展
第8章 scala如何支持OOP
第9章 继续探索scala功能-使用trait
第10-13章 scala对象系统、集合库、课件行规则,详细讲解了对象模型和库类型
第14章 scala如何对java的public protected private可见性概念进行细粒度扩展
第15章 更高级的内容
第16章 高级函数式编程
第17章 并发工具
第18章 scala与大数据
第19章 scala动态调用
第20章 scala的领域特定语言
第21章 scala的工具和库
第22章 scala与java交互
第23章 应用程序设计
第24章 元编程 宏与反射
第一章:scala简介
整体介绍了,scala命令,scala与java进行对比;scala程序执行方式(scala 、sbt);第一个 hello world程序;scala的两个小程序展示了scala的lamba表达是,以及模式匹配,以及并发编程框架akka。
Scala 是 Scalable Language的缩写,意为可扩展的语言。
几个知识点:
- scala工程编译打包工具,执行sbt将进入一个REPL环境
- REPL = read eval print loop
- REPL中 :load src/main/scala/xxx/xxx/abc.sc 加载执行该文件
- scala .sc .scala 以及 scalac -Xscript scala用法
- “_” 通配符
- case类 自动生成 apply toString equals copy 等方法
- scala伴生类 (object and class)
- sbt用法 complile run run-main console 等 help 查看帮助
- 嵌套导入
- 偏函数 PartialFunction[Any,Unit]
- 插值字符串 s”abcd ${xxx}”
- scala方法名可以是符号,以及方法只接受单一参数时可以省略 “.” 和 括号语法糖
- 并发akka简单用法
第二章:更简洁、更强大
本章介绍了 Scala 编程的实践基础、如字面量、关键字,文件的组织与导入,整体还是承接第一章,对scala语法进行更全面的介绍。
知识点:
- 分号
- 变量的声明和初始化 var val
- Range的使用 to until by
- 偏函数 PartialFunction[Any, String…] 偏函数的“链式”连接 orElse 偏函数的 isDefineAt([Any]) 返回true false 避免抛出 MatchError
- 方法声明,方法默认值和参数列表,方法多参数列表的使用
- Future的使用 函数回调
- 嵌套方法定义与递归、参数作用域,为递归注解编译校验@tailrec
- 类型推断,以下情况需要显式声明类型:声明了可变、不可变的变量但未初始化;抽象声明;参数变量
- 数据类型以及 取值范围;字符串的 “”” “””
- 关键字、符号、元组
- Option、Some、None
- seald关键字告诉编译器,子类必须在同一个源文件中,可以防止派生,自定义子类
- 用户空间和命名代码,沿用java的包的方法,但是文件路径和包路径可以不一致
- scala导入的通配符是”_”而 java的是 “*”
- import可以放在任何位置,所以可以将其可见性限制在需要的作用域中,可以在导入时对类型做重命名
- 抽象类型和参数化类型
第三章:要点详解
本章从语法上对Scala进行了比较全面的介绍,包括操作符、符号优先级、流程控制(if while for)、trait、枚举、异常处理、日志等。
知识点:
- 操作符重载,scala中的操作符不是关键字,可以用来声明方法,scala的世界里java的基础类型 int、double、long等都变成了对象,因此可以拥有成员方法
- 语法糖 单一参数方法 可以省略掉前面的”.” 和后面的方法括号
- 无参方法可以灵活定义是否包含括号
- scala由于这些灵活的特性,特别适合用作领域特定语言(DSL),DSL目的是为了简介表达该领域的概念
- if、for、while、do while语法详解
- for推到中的guard
for( x <- seq(1, 2, 3) if x > 1) yield
- for推倒中的Yielding yield关键字,for推倒会自动过滤NONE,生成新的集合
- catch 中的异常case语句以及 NonFatal
第四章 模式匹配
本章讲解了各种情况下的模式匹配,点单匹配、元组、对象、类型、正则表达式等,模式匹配是scala语言中重要的一个功能,可以极大简化代码量。 模式匹配会鼓励开发者多用getter setter暴露属性,
知识点:
- 除了偏函数所有的,所有的match语句必须是完全覆盖所有输入的。当输入类型为Any时,在结尾用case _ 或 case some_name作为默认语句。
- 类型匹配
case i:int => "int value" i
- case中的变量;参数中的变量
def checkY(y: Int) = { for { x <- Seq(99,88,77)}{ val str = x match { case "y" …}
这里y需要加上”`” - Nil 表示非空集合
- 序列的匹配:用模式和递归的方式进行匹配 顺序匹配 +: 逆序匹配 :+
- 序列匹配:unapplySeq 用法可以匹配序列前n个值
eg. case Seq(head1, head2, _*) => ...
- case中的guard
eg. case a:Int if a > 5 : a+1
- zipWithIndex 时,返回的元组形式为 ((name,cost),index)
- 语法糖:包含两个类型参数的类型(类class),可以写成中缀表达式,如序列模式匹配中的”:+”
- 匹配可变参数 :name @ _ 定义可变参数 T
- 正则表达式匹配 定义正则表达式
val regx = '''Book: title=([^,]+),\s+author=(.+)’’’.r case regx(title, author) => s"$title $author"
- 对象匹配中同时想引用对象
case p @ Person("Tom”, 23, address) => …
, 其中 p @ … 语法将将整个Person类的实例都赋值给了 p - 泛型集合匹配 case a : Seq[Int] 错误语法 JVM字节码中不会记住一个泛型的实例;
def doSeqMatch(seq : Seq[T]): String = seq match { case Nil => … \\\ case head +: _ => head match { case …}
可以进行case嵌套来判定集合中具体的类型 - 对于偏函数和全覆盖模式匹配(seald对象、枚举)可以没有默认匹配
- 变量声明也可以使用模式匹配
val Person(name, age) = Person("TOM”, 12) ; val head +: tail = Seq(1, 2, 3, 4)
- for 循环中的模式匹配 如
for{ Some(breed) <- breeds; uppercaseBreed = breed.toUpperCase() } println(uppercaseBreed)
第五章 隐式详解
隐式implicit 是scala的一大特性,同时也是一个可能存在争议的特性。使用隐式能够减少代码,能够向现有的类中注入新的方法。另,隐式在最新版本中已经不推荐使用
知识点:
- 隐式参数
- 限定可用实例
<: eg. def apply \[ R <: { def close():Unit }, T] (resource: => R)(f: R => T) = {…}
- 隐式证据 <:<[A, (U, T)] 或者 A <:< (U, T) eg.
def toMap [T, U](implicit ev: <:<[A, (T, U)]): immutable.Map[T, U]
- 绕开类型擦除带来的限制
eg. def m(seq: Seq[Int])(implicit i: IntMarker.type): Unit
附录:
尾递归:
【形式上】如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。
【本质上】递归函数自身的调用在函数最后,调起的新函数不依赖之前函数的上下文环境,因此很多编译器可以对尾函数进行优化,避免栈溢出的情况。