猜你喜欢
Scala编程(第5版)

Scala编程(第5版)

书籍作者:Martin Odersky ISBN:9787121428326
书籍语言:简体中文 连载状态:全集
电子书格式:pdf,txt,epub,mobi,azw3 下载次数:6101
创建日期:2023-02-16 发布日期:2023-02-16
运行环境:PC/Windows/Linux/Mac/IOS/iPhone/iPad/Kindle/Android/安卓/平板
内容简介

本书由直接参与 Scala 开发的一线人员编写,深入介绍了 Scala 这门结合面向对象和函数式的编程语言的核心特性和设计取舍。继第 4 版后,时隔一年,本书迎来重大更新,内容覆盖 Scala 3.0,对新的缩进语法、并集类型、交集类型、枚举、代数数据类型、上下文参数、特质参数、扩展方法、类型族等都有详细介绍。本书适合有一定编程经验的开发者阅读,尤其是对 Scala 3.0 新特性感兴趣的开发者朋友。即便是不直接使用 Scala 的读者,也能从本书中学到大量关于函数式和面向对象的编程概念和技巧。

作者简介

Martin Odersky 是 Scala 编程语言的缔造者。他是瑞士洛桑理工学院(EPFL)的教授,同时也是 Lightbend 的创始人。他的研究方向是编程语言和系统,更具体地说,就是如何将面向对象和函数式编程风格有机地结合在一起。自 2001 年起,他的主要精力集中在设计、实现和改进 Scala 上。在此之前,他作为 Java 泛型的合作设计者参与了 Java 编程语言的开发,同时也是当前 javac 参考实现的作者。他还是 ACM 院士。

Lex Spoon 是 Semmle Ltd. 的一名软件工程师。作为博士后,他在 EPFL围绕着 Scala 开展了大约两年的工作。他拥有 Georgia Tech 的博士学位,在那里他的主攻方向是动态编程语言的静态分析。除 Scala 外,他还帮助开发了各类编程语言,包括动态语言 Smalltalk、科学计算语言 X10,以及支撑 Semmle的逻辑编程语言。他和他的夫人一起生活在 Atlanta,他们有两只猫和一只吉娃娃。

Bill Venners 是 Artima Inc.的总裁,Artima 开发者网站的发行人,提供Scala 咨询、培训、书籍和工具。他著有《深入 Java 虚拟机》,这是一本面向程序员讲解 Java 平台架构和内部实现原理的书。他在 JavaWorld 杂志上的专栏很受欢迎,主题涵盖 Java 内部实现、面向对象的设计和 Jini。Bill 是 ScalaCenter 咨询委员会的社区代表,还是测试框架 ScalaTest 和针对函数式、面向对象编程类库 Scalactic 的主要开发者和设计者。

Frank Sommers 是 Autospaces Inc.的创始人和总裁,该公司为金融服务行业提供自动化的工作流解决方案。在过去的 12 年间,Frank Sommers 一直是活跃的 Scala 用户,几乎每天都在使用这门编程语言。

译者:高宇翔,资深软件开发工程师和系统架构师,同时也是Scala在国内的早期布道者和实践者,曾译有《Scala编程》(第1版)、《Scala编程》(第3版)、《Scala编程》(第4版),以及《快学Scala》(第1版)、《快学Scala》(第2版)等广为人知的Scala语言技术名著。


中文版审校者:钟伦甫,Scala爱好者和早期布道者。2012年在淘宝中间件团队任职技术专家期间,用Scala编写过一款名为HouseMD 的JVM诊断工具并开源。后又作为联合译者,参与了《Scala函数式编程》一书的翻译;黄胜涛,有10年以上系统运维和8年以上软件开发经验,曾就职于携程旅行网、LOTTE,目前在上海昱极科技有限公司从事DevOps方面工作。

编辑推荐

《Scala编程(第5版)》是Scala的权威图书,涵盖语言基础与重要类库,可被奉为圭臬的领域重要参考书。。Scala是Java平台上的一门功能强大的主流语言,它以独到的方式将面向对象和函数式编程的概念有机地结合在一起,供开发者使用。本书由Scala语言设计者编写,将循序渐进地向你介绍Scala编程语言和它背后的设计理念。本书几经迭代,编排、组织精细。开始几章教你足够多的基础知识,让你直接上手用Scala处理简单任务。本书严格遵循这样的原则:新概念都基于已出现过的概念,通过阶梯式教学,让你逐步掌握语言及其背后的设计理念。第5版是重磅新版,全面升级到Scala 3.0,并对以下特性进行详细介绍:

√枚举和代数数据类型

√上下文参数

√扩展方法

√安静语法和可选花括号

√特质参数

√并集类型和交集类型

√导出子句

√顶层定义


前言

译者序

Scala3终于来了。

这是一次重大的更新。Scala编辑器从底层开始被全部重写。不得不说,这也是Scala创始团队的一次冒险,毕竟已经有很多成功的公司、团队和个人在早期版本,尤其是Scala2.8之后的Scala生态中找到了自己的位置、大量以Scala编写的类库和业务代码在线上运行。

可Martin Odersky 和他的团队就是聊足了劲要升级,想从根本上“修复”那些让Scala还不够理论完备的设计。但是理论完备有那么重要吗?站在编程语言设计者的角度。我倾向于肯定的答案。而站在使用者的角度。我更关心它带来了那些变化,以及我能不能在使用中适症这些变化

让我颇感意外的是,真正上手Scala3,并没有想象中的那么困难重重。甚至抱受争议的缩进语法,也没有带来任何不适。原有的代码不需要修改,或者仅仅需要少量修改。就能顺利地通过Scala3的编译。你很难相信这是一门全新的、从里到外重新实现的编程语言。

经过短暂的适应期。Scala3的诸多新特性,如枚举、上下文参数、扩展方法和类型族等,都能被我灵活运用。这些新特性初看起来各有各的模样,并且实际使用下来,也多少都带着一些新编译器的“味道”,但是你能“嗅”到类型系统的某种一致性。Scala一直能在很多看似完全不同的概念之间找到关联、似乎总能透过表象,直面本质。这种感觉很微妙、让人既有些新奇,又非常熟悉。

Scala 社区这几年也有非常大的变化和进步,最值得一提的是,ZIO 这个面向“作用”(effect)的编程类库对业务代码中常见的模式进行了非常有洞见性的抽象,将函数式编程以一种类型健壮且高效的方式引人一线开发者的工具库中。很自然地,ZIO 在顺利发布1.0版本之后,随着Scala 3的发布,也在第一时间全面“拥抱”Scala 3。

你手中的这本《Scala 编程》已经是第5版,这一版针对Scala3进行了全面的更新。更新主要体现在两个方面:首先,增加了对 Scala3主要的新特性的介绍,所有内容和示例代码都基于Scala3重新梳理和编写;其次,在篇幅上进行了大幅度调整,最显著的是把《Scala 编程》拆成了两卷,第一卷也就是现在这本《Scala编程》,它保留了 Scala 编程语言核心功能特性和设计理念的内容,让大家能够快速地理解、掌握并使用Scala编写实用的类库和业务代码,而第二卷为《Scala高级编程》,它将包含更多高级主题,且单独成册,面向那些对 Scala高级特性(如宏和元编程)感兴趣的读者。

感谢 Martin Odersky 和他的团队为我们带来这样一门独特而优雅的编程语言,并且不惜冒着社区分化的风险(现在看来这个担心很可能是多余的)坚持对语言核心进行升级;感谢电子工业出版社及张春雨编辑,在第1版、第3版和第4版之后,继续引进本书的第5版;感谢编辑团队和其他幕后工作者的辛勤付出;感谢家人无条件的支持和鼓励,你们是我永远的挚爱。

在本书的翻译过程中,译者虽已尽力忠实呈现原著的本意,但毕竟能力有限,问题和疏漏恐难以避免,恳请各位读者批评指正、联系地址: [email protected]

高宇翔 2021年于上海


见证一门新编程语言的诞生是一件有趣的事。对任何一位使用编程语言的人而言——无论你是首次尝试编程的人还是职业软件工程师——编程语言看起来就在那里。就像锤子或斧子一样,编程语言也是一种工具,让我们可以做我们想做的。我们很少会想到工具是怎么来的,它的设计过程是怎样的。或许我们对工具的设计有自己的看法,但除此之外,我们通常只能接受并运用它。

编程语言的创造过程让我有了完全不同的视角。各种可能性似乎无穷无尽。同时,编程语言也必须满足看起来同样无穷无尽的各种约束。这是一种奇怪的张力。

创造一门新的编程语言有很多方面的原因,例如,某种个人想要解决的“痛点”,或者某种学术上的洞见,或者技术债,或者其他编译器架构的潜在收益,甚至可能是政治因素。对Scala 3的创造而言,上述原因多少都有一些。

无论出于何种原因,一切都开始于Martin Odersky在某一天突然消失,当他几天后再次出现在某个研究组会议上时,他向大家正式宣告自己已经开始尝试从零起步编写一个全新的编译器,将DOT演算 实施落地。而在场的我们是一群博士研究生和博士后,在那之前主要负责Scala 2的开发和维护。当时,Scala看起来正在接近看上去难以企及的成功高度,尤其是对于这样一门诞生于瑞士的、一个听起来有些奇怪的学校的偏门学术编程语言。然而就在不久前,Scala得到了旧金山湾区的很多创业公司的追捧,成立了Typesafe也就是后来的Lightbend,专注于支持、维护和管理Scala 2。那么为什么突然要做一个全新的编译器,以及由此带来的不一样的编程语言呢?我们当中的大多数人对此心存疑虑,但Martin Odersky已经下定了决心。

几个月过去了。就像上了发条一样,每天中午12点,整个实验室的人都会出现在连接各个办公室的门厅。当聚集了一定数量的人员以后,我们就会一起来到EPFL的某个餐厅吃午饭,并享用饭后咖啡。在每天都会举行的这个“仪式”中,关于新编译器的想法是反复出现的讨论话题,例如,从“150%”兼容Scala 2(避免陷入Python 2和Python 3的困境),到创造一门全新的“全光谱”依赖类型编程语言。

研究组中持怀疑态度的人,一个接一个地被Scala 3的某个特性征服,比如,对类型检查器的精简,全新的编译器架构,以及对类型系统的增强等。随着时间的推移,社区主流也认为Scala 3相比Scala 2而言具有显著的改进。对于这个结论,不同的人有不同的理由。对有些人而言,是因为Scala 3将花括号和条件判定语句的括号变为可选的,从而改善了可读性。对其他人而言,是因为Scala 3的类型系统更强了。如此种种。

我可以很有信心地说,Scala 3的设计并不是完全依靠直觉的“闭门造车”,而是吸纳了过去设计的宝贵经验,以及EPFL研究组和Scala社区的多年沟通与交流经验。并且,除从头开始在全新的“地基”上搭建之外,别无他途。既然Scala 3是从头开始设计的,其内核就是一门全新的编程语言。

Scala 3是一门全新的编程语言。诚然,它兼容Scala 2,听起来像是一门已经存在的编程语言的第三个重大版本。但是不要被这个影响了你的判断,Scala 3实现了在Scala 2中先行试验、探索的诸多想法的重大精简。

在Scala 3的所有特性中,可能最“Scala”的一个专属的变化是对隐式的改动。Scala从一开始就被聪明的程序员们用来实现某种基于Scala特性本就很少有人能想到的功能,更别提这些功能与Scala设计本意的背离程度有多大了。这个先前被称作隐式的特性可能是Scala中最著名的被用来以各种奇怪的方式改变Scala 2代码行为的功能点了。隐式的使用场景包括:对一个类在“事后”追加方法,不扩展也不重新编译;或者,在某种特定的上下文中,基于某种类型签名,自动选择适用于该上下文的正确实现。上述只是冰山一角——我们甚至为此写了一篇论文以对开发人员使用隐式的各种方法进行归类。

这就像是把旋钮和杠杆交给用户,期待他们能做出一台精密的仪器,如机械计算器。但通常我们得到的是类似于Theo Jansen的动力雕塑,而不是某种能一眼看出用途的物件。简单而言,如果你交给编程社区的是一些旋钮和杠杆,则社区中那些强悍的选手总能找到这些工具的创新用法。这是人的本性。不过可能正是在这里,Scala 2犯了错误,将最基础、最通用的旋钮和杠杆交给了程序员。

我想说的是,在Scala 2中,隐式有无穷无尽的可能性,这些可能性足够我们撰写研究生论文,而社区对于如何使用隐式并没有一个统一的认识。这种没有清晰用途的编程语言特性不应该存在。但是很可惜,隐式就是这样一种存在:很多人将隐式看作Scala独有的强大功能,没有其他语言能做到;还有很多人认为隐式是神秘且经常令人困惑的机制,会侵入你的代码,将你的代码改得面目全非。

你可能已经听说过很多种不同形式的表述,但Scala 3代表了这之前所有Scala版本的简化版本。隐式是一个很好的例子。在意识到那些“后空翻”程序员希望通过隐式来实现更广泛的编程模式[如类型族(typeclass)派生]后,Martin Odersky在其他人的帮助下得出的结论是,我们不应该把注意力集中在人们一般如何使用隐式作为编程机制,而应该关注程序员们想用隐式做什么,然后把这个目标变得更加容易且高效。这就是口头禅“Scala 3专注于意图而不是机制”的来源。

Scala 3并不把注意力集中在作为编程机制的隐式的通用性上,而是关注开发人员在使用隐式时想要满足的特定使用场景,让其用起来更加直接。例如,隐式地将上下文或配置信息传递给某方法,而不需要程序员显式地给出重复的参数;在“事后”给类追加方法;在算术运算中对不同类型的值进行转换。如今,Scala 3将这些使用方法直接提供给程序员,使他们不需要“深入”理解Scala编译器如何解析隐式值,只需要关心“在不重新编译Bar类的前提下给Bar类追加foo方法”这样的任务即可;不需要具有博士学位,只需要把之前的“隐式”替换成其他更直接的与特定使用场景相关的关键字即可,如given和using。更多内容参见第21章和第22章。

“专注于意图而不是机制”的故事并不止于对隐式的改造,这个设计哲学几乎贯穿了这门语言的方方面面。例如,对Scala类型系统的增强和简化,包括并集类型(union type)、枚举(enum)、匹配类型(match type)等;对Scala语法的清理,包括if、else、while,让条件判断读起来更像英文。

当然,我说的这些,你不必盲目相信。无论你是Scala新手还是有经验的Scala开发人员,我希望你和我一样,Scala 3所包含的许多新的设计理念能让你感到耳目一新且直截了当!

——Heather Miller 瑞士洛桑



引言

本书是Scala编程语言的教程,由直接参与Scala开发的人来编写。我们的目标是让读者通过本书,能够了解和掌握成为高产的Scala程序员需要知道的一切。书中的所有示例均能通过Scala 3.0.0的编译。

谁读本书

本书主要的目标读者是希望学习如何使用Scala编程的人。如果你想在你的下一个项目中使用Scala,本书就是为你准备的。除此之外,本书对于那些想要学习新知识从而开阔自己眼界的程序员也同样有益。比方说,如果你是Java程序员,那么阅读本书,你将接触到来自函数式编程领域和高阶面向对象领域的许多概念。我们相信,通过学习Scala及Scala背后的观念,你将成为一名更好的程序员。

我们假定你拥有常规的编程知识。虽然Scala作为用于入门的编程语言并没有什么不妥,但是本书并不适用于(从零开始)学习编程。

另一方面,阅读本书并不要求读者具备某项具体的编程语言的知识。我们当中大部分人都是在Java平台上使用Scala的,但本书并不假定你了解Java本身。不过,我们预期大部分读者都熟悉Java,因此我们有时会将Scala与Java做对比,帮助这些读者理解它们之间的区别。

如何使用本书

本书的主旨是教学,我们推荐的阅读顺序是从前到后,依次阅读各章。我们尽可能每次只引入一个主题,同时只使用已经介绍过的主题来解释这个新的主题。因此,如果你跳过前面的章节,则可能会遇到某些并不十分理解的概念。只要你按顺序阅读,就会发现掌握Scala是循序渐进、顺理成章的。

如果你看到某个不明白的词汇,记得查看术语表。许多读者都喜欢快速浏览特定的章节,这没有问题,目录能帮助你随时找回阅读的坐标和方位。

当你读完本书以后,还可以继续将其当作语言参考书。Scala编程语言有一份正式的语言规范,但语言规范强调的是精确性,而不是可读性。虽然本书不会覆盖Scala的每一个细节,但是它也足够全面,应该能够在你逐渐成为Scala编程能手的过程中,承担起语言参考书的职责。

如何学习Scala

通读本书,你可以学到很多关于Scala的知识。不过,如果你做一些额外的尝试,则可以学得更快,更彻底。

首先,利用好包含在本书中的代码示例。手动将这些代码示例录入,有助于在脑海中逐行过一遍代码。尤其是在录入过程中尝试一些变化,会非常有趣,这也能让你确信自己真的理解了它们背后的工作原理。

其次,时常访问在线论坛。这样,你和其他Scala爱好者可以互相促进。网上有大量的邮件列表、讨论组、聊天室、Wiki和Scala特定主题的订阅。花费一些时间,找到满足你需求的内容,你会在小问题上花更少的时间,有更多的时间和精力投入更深入、更重要的问题中。

最后,一旦你读得足够多,就可以自己启动一个编程项目。例如,从头编写小程序,或者为某个更大的项目开发组件,因为仅仅阅读并不会让你走得更远。

内容概览

61 第1章,“一门可伸缩的语言”,主要介绍Scala的设计及背后的概念和历史。

61 第2章,“Scala入门”,介绍了如何使用Scala完成一些基础的编程任务,但并不深入讲解它是如何工作的。本章的目标是让你可以开始输入Scala代码并执行。

61 第3章,“Scala入门(续)”,展示了更多基本的编程任务,帮助你快速上手Scala。学习完本章以后,你应该就能使用Scala完成简单的脚本型任务了。

61 第4章,“类和对象”,开始深入介绍Scala,描述其基本的面向对象的组成部分,并指导大家如何编译并运行Scala应用程序。

61 第5章,“基本类型和操作”,介绍了Scala基本类型、字面量和支持的操作,(操作符的)优先级和结合律,以及对应的富包装类。

61 第6章,“函数式对象”,以函数式(即不可变)的分数为例,更深入地讲解Scala面向对象的特性。

61 第7章,“内建的控制结构”,展示了如何使用Scala内建的控制结构:if、while、for、try和match。

61 第8章,“函数和闭包”,给出了对函数的深入介绍,而函数是函数式编程语言最基本的组成部分。

61 第9章,“控制抽象”,展示了如何通过定义自己的控制抽象来对Scala基本的控制结构进行完善和补充。

61 第10章,“组合和继承”,更进一步探讨Scala对面向对象编程的支持。本章的主题不像第4章那么基础,但在实践中经常会遇到。

61 第11章,“特质”,介绍了Scala的混入组合机制。本章展示了特质的工作原理,描述了特质的常见用法,并解释了特质相对于更传统的多重继承有哪些改进。

61 第12章,“包、引入和导出”,讨论了大规模编程实践中我们会遇到的问题,包括顶级包,import语句,以及像protected和private那样的访问控制修饰符。

61 第 13 章,“样例类和模式匹配”,介绍了这组孪生的结构。它们在处理树形的递归数据时非常有用。

61 第14章,“使用列表”,详细地解释了列表这个在Scala程序中使用最普遍的数据结构。

61 第15章,“使用其他集合类”,展示了如何使用基本的Scala集合,如列表、数组、元组、集和映射。

61 第16章,“可变对象”,解释了可变对象,以及Scala用来表示可变对象的语法。本章以一个具体的离散事件模拟案例分析收尾,展示了实践中可变对象的适用场景。

61 第17章,“Scala的继承关系”,解释了Scala的继承关系,并探讨了通用方法和底类型等概念。

61 第18章,“类型参数化”,使用具体的示例解释了第13章介绍过的信息隐藏的技巧:为纯函数式队列设计的类。本章接下来对类型参数的型变进行了说明,介绍了类型参数化对于信息隐藏的作用。

61 第 19 章,“枚举”,介绍了枚举和代数数据类型(ADT)这组孪生的结构,让你更好地编写规则的、开放式的数据结构。

61 第20章,“抽象成员”,描述了Scala支持的各种抽象成员,不仅方法可以被声明为抽象的,字段和类型也可以。

61 第21章,“上下文参数”,介绍了Scala如何帮助你对函数使用上下文参数。将所有的上下文信息都直接带入并不是什么难事,但会因此增加很多样板代码,上下文参数能帮助你减少一些样板代码。

61 第22章,“扩展方法”,介绍了Scala如何让一个在类定义之外的函数看起来像是类自己定义的那样的机制。

61 第23章,“类型族”,展示了类型族的若干示例。

61 第24章,“深入集合类”,详细介绍了Scala集合类库。

61 第25章,“断言和测试”,展示了Scala的断言机制,并介绍了用Scala编写测试的若干工具,特别是ScalaTest。

目录

序 XIX
引言 XXIII
第1章 一门可伸缩的语言 1
1.1 一门按需伸缩的语言 2
1.2 是什么让Scala能屈能伸 6
1.3 为什么要用Scala 9
1.4 Scala寻根 17
1.5 结语 19
第2章 Scala入门 20
第1步 使用Scala解释器 21
第2步 定义变量 22
第3步 定义函数 25
第4步 编写Scala脚本 27
第5步 用while做循环;用if做判断 29
第6步 用foreach方法和for-do遍历 31
结语 34
第3章 Scala入门(续) 35
第7步 用类型参数化数组 35
第8步 使用列表 40
第9步 使用元组 44
第10步 使用集和映射 45
第11步 识别函数式编程风格 50
第12步 用map方法和for-yield变换 53
结语 57
第4章 类和对象 58
4.1 类、字段和方法 58
4.2 分号推断 63
4.3 单例对象 64
4.4 样例类 67
4.5 Scala应用程序 69
4.6 结语 71
第5章 基础类型和操作 72
5.1 一些基础类型 72
5.2 字面量 73
5.3 字符串插值 79
5.4 操作符即方法 81
5.5 算术操作 84
5.6 关系和逻辑操作 85
5.7 位运算操作 87
5.8 对象相等性 88
5.9 操作符优先级和结合律 90
5.10 富包装类 93
5.11 结语 94
第6章 函数式对象 95
6.1 Rational类的规格定义 95
6.2 构建Rational实例 96
6.3 重新实现toString方法 98
6.4 检查前提条件 99
6.5 添加字段 100
6.6 自引用 102
6.7 辅助构造方法 103
6.8 私有字段和方法 105
6.9 定义操作符 106
6.10 Scala中的标识符 108
6.11 方法重载 111
6.12 扩展方法 113
6.13 注意事项 114
6.14 结语 115
第7章 内建的控制结构 116
7.1 if表达式 117
7.2 while循环 118
7.3 for表达式 121
7.4 用try表达式实现异常处理 127
7.5 match表达式 131
7.6 没有break和continue的日子 133
7.7 变量作用域 135
7.8 对指令式代码进行重构 139
7.9 结语 141
第8章 函数和闭包 142
8.1 方法 142
8.2 局部函数 143
8.3 一等函数 145
8.4 函数字面量的简写形式 147
8.5 占位符语法 148
8.6 部分应用的函数 149
8.7 闭包 152
8.8 特殊的函数调用形式 154
8.9 SAM类型 158
8.10 尾递归 159
8.11 结语 163
第9章 控制抽象 164
9.1 减少代码重复 164
9.2 简化调用方代码 168
9.3 柯里化 170
9.4 编写新的控制结构 172
9.5 传名参数 175
9.6 结语 178
第10章 组合和继承 179
10.1 一个二维的布局类库 179
10.2 抽象类 180
10.3 定义无参方法 182
10.4 扩展类 184
10.5 重写方法和字段 187
10.6 定义参数化字段 188
10.7 调用超类构造方法 189
10.8 使用override修饰符 191
10.9 多态和动态绑定 192
10.10 声明final成员 195
10.11 使用组合和继承 196
10.12 实现above、beside和toString方法 198
10.13 定义工厂对象 201
10.14 增高和增宽 204
10.15 放在一起 205
10.16 结语 207
第11章 特质 208
11.1 特质如何工作 208
11.2 瘦接口和富接口 211
11.3 作为可叠加修改的特质 214
11.4 为什么不用多重继承 218
11.5 特质参数 223
11.6 结语 225
第12章 包、引入和导出 227
12.1 将代码放进包里 227
12.2 对相关代码的精简访问 229
12.3 引入 232
12.4 隐式引入 236
12.5 访问修饰符 237
12.6 顶层定义 242
12.7 导出 243
12.8 结语 247
第13章 样例类和模式匹配 248
13.1 一个简单的例子 248
13.2 模式的种类 253
13.3 模式守卫 264
13.4 模式重叠 265
13.5 密封类 267
13.6 对Option进行模式匹配 269
13.7 到处都是模式 271
13.8 一个复杂的例子 276
13.9 结语 284
第14章 使用列表 285
14.1 List字面量 285
14.2 List类型 286
14.3 构建列表 287
14.4 列表的基本操作 287
14.5 列表模式 289
14.6 List类的初阶方法 291
14.7 List类的高阶方法 303
14.8 List对象的方法 311
14.9 同时处理多个列表 313
14.10 理解Scala的类型推断算法 315
14.11 结语 319
第15章 使用其他集合类 320
15.1 序列 320
15.2 集和映射 324
15.3 在可变和不可变集合之间选择 331
15.4 初始化集合 334
15.5 元组 337
15.6 结语 340
第16章 可变对象 341
16.1 什么样的对象是可变的 341
16.2 可被重新赋值的变量和属性 344
16.3 案例分析:离散事件模拟 347
16.4 用于描述数字电路的语言 348
16.5 模拟API 351
16.6 电路模拟 356
16.7 结语 363
第17章 Scala的继承关系 365
17.1 Scala的类继承关系 365
17.2 基本类型的实现机制 369
17.3 底类型 371
17.4 定义自己的值类型 372
17.5 交集类型 376
17.6 并集类型 377
17.7 透明特质 380
17.8 结语 382
第18章 类型参数化 383
18.1 函数式队列 383
18.2 信息隐藏 387
18.3 型变注解 390
18.4 检查型变注解 396
18.5 下界 399
18.6 逆变 401
18.7 上界 404
18.8 结语 407
第19章 枚举 408
19.1 枚举数据类型 408
19.2 代数数据类型 413
19.3 泛化代数数据类型 415
19.4 为什么说ADT是代数数据类型 416
19.5 结语 420
第20章 抽象成员 421
20.1 抽象成员概览 421
20.2 类型成员 422
20.3 抽象的val 423
20.4 抽象的var 424
20.5 初始化抽象的val 425
20.6 抽象类型 433
20.7 路径依赖类型 436
20.8 改良类型 438
20.9 案例分析:货币 439
20.10 结语 450
第21章 上下文参数 451
21.1 上下文参数的工作原理 452
21.2 参数化的上下文参数类型 456
21.3 匿名上下文参数 461
21.4 作为类型族的参数化上下文参数 463
21.5 上下文参数的引入 466
21.6 上下文参数的规则 468
21.7 当有多个上下文参数可选时 471
21.8 调试上下文参数 473
21.9 结语 475
第22章 扩展方法 476
22.1 扩展方法的基础 476
22.2 泛化的扩展方法 479
22.3 成组的扩展方法 481
22.4 使用类型族 484
22.5 针对上下文参数的扩展方法 486
22.6 Scala如何查找扩展方法 491
22.7 结语 492
第23章 类型族 493
23.1 为什么要用类型族 493
23.2 上下文界定 499
23.3 主方法 502
23.4 跨界相等性 506
23.5 隐式转换 512
23.6 类型族案例分析:JSON序列化 515
23.7 结语 526
第24章 深入集合类 527
24.1 可变和不可变集合 528
24.2 集合的一致性 530
24.3 Iterable特质 532
24.4 序列型特质Seq、IndexedSeq和LinearSeq 539
24.5 集 544
24.6 映射 548
24.7 具体的不可变集合类 553
24.8 具体的可变集合类 560
24.9 数组 565
24.10 字符串 570
24.11 性能特征 571
24.12 相等性 573
24.13 视图 574
24.14 迭代器 579
24.15 从头创建集合 585
24.16 Java和Scala集合互转 587
24.17 结语 589
第25章 断言和测试 590
25.1 断言 590
25.2 用Scala写测试 592
25.3 翔实的失败报告 594
25.4 作为规格说明的测试 596
25.5 基于属性的测试 599
25.6 组织和运行测试 601
25.7 结语 603
术语表 604
关于作者 627