Implementing Lists
这一章主要讲List在Scala中是如何实现的
List在Scala中并不是一个内置的结构,而是定义在一个抽象类 List 中,它有两个子类: :: 以及 Nil。 :: 是一个final class,而 Nil则是一个Object。List类中只有三个方法: isEmpty, head, tail等
List的一些内置方法,如 length,drop,map 都可以通过递归来实现
List的构造方法有两种: :: 以及 ::: ,默认它们都是与右边的操作数绑定。 That is, an operation such as x::xs is treated as the method call xs.::(x), not x.::(xs)
:: 接受一个参数,并返回一个新的List,因为List是属于 covariant,所以新的List类型可能与原来类型不同,可以参考 :: 定义
def :: [U>:T](x:U):List[U]=new scala.::(x,this)
List的内部实现大量使用了 ListBuffer,这是属于一个 mutable的集合,可以很方便的进行各种List操作,如把元素添加到尾部(利用 += 符号),最后完成操作,可以利用 toList 就可以将 ListBuffer 转换成 List, both append operation (+=) and the toList operation take constant time. 不过,一些关键的实现点自己还没有弄明白
虽然List内部实现使用了 mutable 的结构,但是其外在表现则是 immutable。不过,如果你想使用 mutable 的结构,则可以选择使用 ListBuffer。这种关系有点类似于Java中的 String 与 StringBuffer一样: For Scala’s lists, you can either construct lists incrementally by adding elements to the beginning of a list using ::, or you use a list buffer for adding elements to the end.
For Expressions Revisited
这一章主要介绍 for 表达式。 For表达式的出现,可以使代码更易读。有时当使用太多的高阶函数时,会导致代码易读性降低,那么这时就可以选择使用 for 表达式了。另外,for 表达式的作用还不只于此。for 表达式还可以与 monad 结合(不懂这什么意思?),或者用于异步I/O
for 表达式有两种形式,一种是具有返回值,这是需要使用关键字 yield;另一种就如普通的 for 语句,不需要 yield 关键字了
for 表达式与高阶函数有很大的联系。In fact, all for expression that yield a result are translated by the compiler into combinations of invocations of the high-order methods map, flatMap, and filter; all for loops without yield are translated into a smaller set of higher-order functions: just filter and foreach.
for 表达式的一般形式如下:
for ( seq ) yield expr
Here, seq is a sequence of generators, defintions and filters
Every for expression starts with a generator. If there are several generators in a for expression, later generators vary more rapidly than earlier ones.
Every for expression can be expressed in terms of the three higher-order functions map, flatMap**, and filter.
如果 for 表达式含有 pattern,那么对应转换成高阶函数时就需要用到 pattern matching
当转换for 表达式的变量定义时,要注意每当产生一个新的元素时,原来的表达式(定义变量)就会被重新evaluate一次,所以最好把一些无关的表达式写在 for 表达式外
for表达式可以用高阶函数来表达,同样地,高阶函数也可以用for表达式来表达
如果你想要自己的数据类型支持 for表达式 ,那么你就需要定义 map, flatMap, filter, foreach,可以参考以下规则:
If your type defines just map, it allows for expressions consisting of a single generator
If it defines flatMap as well as map, it allows for expressions consisting of several generators
If it defines foreach, it allows for loops (both with single and multiple generators)
If it defines filter, it allows for filter expressions starting with an if in the for expression
下面这段话值得注意(虽然不懂,记下再说): In functional programming, there’s a general concept called a monad, which can explain a large number of types with computations, ranging from collections, to computations with state and I/O, backtracking computations, and transactions, to name but a few. You can formulate functions map, flatMap, and filter, plus a “unit” constructor that produces a monad from an element value. In an object-oriented language, this “unit” constructor is simply an instance constructor or a factory method. Therefore, map, flatMap, filter can be seen as an object-orinted version of the functional concept of monad. Because for expressions are equivalent to applications of these three methods, they can be seen as syntax for monads.