0%

《Scala程序设计(第2版)》读书笔记

章节概述(摘自 序-如何阅读本书)

第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的缩写,意为可扩展的语言。

几个知识点:

  1. scala工程编译打包工具,执行sbt将进入一个REPL环境
  2. REPL = read eval print loop
  3. REPL中 :load src/main/scala/xxx/xxx/abc.sc 加载执行该文件
  4. scala .sc .scala 以及 scalac -Xscript scala用法
  5. “_” 通配符
  6. case类 自动生成 apply toString equals copy 等方法
  7. scala伴生类 (object and class)
  8. sbt用法 complile run run-main console 等 help 查看帮助
  9. 嵌套导入
  10. 偏函数 PartialFunction[Any,Unit]
  11. 插值字符串 s”abcd ${xxx}”
  12. scala方法名可以是符号,以及方法只接受单一参数时可以省略 “.” 和 括号语法糖
  13. 并发akka简单用法

第二章:更简洁、更强大

本章介绍了 Scala 编程的实践基础、如字面量、关键字,文件的组织与导入,整体还是承接第一章,对scala语法进行更全面的介绍。

知识点:

  1. 分号
  2. 变量的声明和初始化 var val
  3. Range的使用 to until by
  4. 偏函数 PartialFunction[Any, String…] 偏函数的“链式”连接 orElse 偏函数的 isDefineAt([Any]) 返回true false 避免抛出 MatchError
  5. 方法声明,方法默认值和参数列表,方法多参数列表的使用
  6. Future的使用 函数回调
  7. 嵌套方法定义与递归、参数作用域,为递归注解编译校验@tailrec
  8. 类型推断,以下情况需要显式声明类型:声明了可变、不可变的变量但未初始化;抽象声明;参数变量
  9. 数据类型以及 取值范围;字符串的 “”” “””
  10. 关键字、符号、元组
  11. Option、Some、None
  12. seald关键字告诉编译器,子类必须在同一个源文件中,可以防止派生,自定义子类
  13. 用户空间和命名代码,沿用java的包的方法,但是文件路径和包路径可以不一致
  14. scala导入的通配符是”_”而 java的是 “*”
  15. import可以放在任何位置,所以可以将其可见性限制在需要的作用域中,可以在导入时对类型做重命名
  16. 抽象类型和参数化类型

第三章:要点详解

本章从语法上对Scala进行了比较全面的介绍,包括操作符、符号优先级、流程控制(if while for)、trait、枚举、异常处理、日志等。

知识点:

  1. 操作符重载,scala中的操作符不是关键字,可以用来声明方法,scala的世界里java的基础类型 int、double、long等都变成了对象,因此可以拥有成员方法
  2. 语法糖 单一参数方法 可以省略掉前面的”.” 和后面的方法括号
  3. 无参方法可以灵活定义是否包含括号
  4. scala由于这些灵活的特性,特别适合用作领域特定语言(DSL),DSL目的是为了简介表达该领域的概念
  5. if、for、while、do while语法详解
  6. for推到中的guard for( x <- seq(1, 2, 3) if x > 1) yield
  7. for推倒中的Yielding yield关键字,for推倒会自动过滤NONE,生成新的集合
  8. catch 中的异常case语句以及 NonFatal

第四章 模式匹配

本章讲解了各种情况下的模式匹配,点单匹配、元组、对象、类型、正则表达式等,模式匹配是scala语言中重要的一个功能,可以极大简化代码量。 模式匹配会鼓励开发者多用getter setter暴露属性,

知识点:

  1. 除了偏函数所有的,所有的match语句必须是完全覆盖所有输入的。当输入类型为Any时,在结尾用case _ 或 case some_name作为默认语句。
  2. 类型匹配 case i:int => "int value" i
  3. case中的变量;参数中的变量def checkY(y: Int) = { for { x <- Seq(99,88,77)}{ val str = x match { case "y" …} 这里y需要加上”`”
  4. Nil 表示非空集合
  5. 序列的匹配:用模式和递归的方式进行匹配 顺序匹配 +: 逆序匹配 :+
  6. 序列匹配:unapplySeq 用法可以匹配序列前n个值 eg. case Seq(head1, head2, _*) => ...
  7. case中的guard eg. case a:Int if a > 5 : a+1
  8. zipWithIndex 时,返回的元组形式为 ((name,cost),index)
  9. 语法糖:包含两个类型参数的类型(类class),可以写成中缀表达式,如序列模式匹配中的”:+”
  10. 匹配可变参数 :name @ _ 定义可变参数 T
  11. 正则表达式匹配 定义正则表达式 val regx = '''Book: title=([^,]+),\s+author=(.+)’’’.r case regx(title, author) => s"$title $author"
  12. 对象匹配中同时想引用对象 case p @ Person("Tom”, 23, address) => …, 其中 p @ … 语法将将整个Person类的实例都赋值给了 p
  13. 泛型集合匹配 case a : Seq[Int] 错误语法 JVM字节码中不会记住一个泛型的实例;def doSeqMatch(seq : Seq[T]): String = seq match { case Nil => … \\\ case head +: _ => head match { case …} 可以进行case嵌套来判定集合中具体的类型
  14. 对于偏函数和全覆盖模式匹配(seald对象、枚举)可以没有默认匹配
  15. 变量声明也可以使用模式匹配val Person(name, age) = Person("TOM”, 12) ; val head +: tail = Seq(1, 2, 3, 4)
  16. for 循环中的模式匹配 如 for{ Some(breed) <- breeds; uppercaseBreed = breed.toUpperCase() } println(uppercaseBreed)

第五章 隐式详解

隐式implicit 是scala的一大特性,同时也是一个可能存在争议的特性。使用隐式能够减少代码,能够向现有的类中注入新的方法。另,隐式在最新版本中已经不推荐使用

知识点:

  1. 隐式参数
  2. 限定可用实例<: eg. def apply \[ R <: { def close():Unit }, T] (resource: => R)(f: R => T) = {…}
  3. 隐式证据 <:<[A, (U, T)] 或者 A <:< (U, T) eg. def toMap [T, U](implicit ev: <:<[A, (T, U)]): immutable.Map[T, U]
  4. 绕开类型擦除带来的限制 eg. def m(seq: Seq[Int])(implicit i: IntMarker.type): Unit

附录:

尾递归:

【形式上】如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。

【本质上】递归函数自身的调用在函数最后,调起的新函数不依赖之前函数的上下文环境,因此很多编译器可以对尾函数进行优化,避免栈溢出的情况。