《Kotlin核心编程》
Kotlin核心编程
水滴技术团队 著
Preface 前 言
为什么要写这本书
2017年5月,Hadi Hariri(JetBrains的首席布道师)在座无虚席的Google I/O大会上介绍Kotlin时,先开了一个玩笑:“大概4年半之前,我们曾在一个容纳900人的会场做过同样的事情,但结果只来了7个人。”
他说的是事实,自从Google宣布Kotlin成为Android官方编程语言之后,Kotlin这门默默无闻的语言一下子成为技术圈中的“明星”。随后,关于Kotlin的开源项目和学习资料也如雨后春笋般出现。
同一时刻,在我们位于杭州的办公室里,水滴的同事也在进行着一个用Kotlin研发的Android项目。作为一个采用Scala全栈开发的“非主流”技术团队,我们对Kotlin有天然的好感。一方面,它在某些地方非常像Scala。相比Java,它们都拥有更简洁的语法,以及更多的函数式特性(如高阶函数、更强的类型推导、不同程度上的模式匹配等)。另一方面,Kotlin还有比Scala更快的编译速度,同时兼容Java 6,这使得我们可以用它完美替代Java以更好地进行Android开发工作。
那么Kotlin到底是怎样一门编程语言呢?我们试图通过这本书来回答这个问题。
与其他Kotlin的书籍不同,本书在工具属性上会显得稍弱。如果你想快速索引Kotlin某个具体语法的使用,推荐你去阅读Kotlin的官方文档或者《Kotlin极简教程》。但假使你有一颗好奇的心,渴望窥探Kotlin这门语言的设计哲学,那么本书可以提供一个浅薄的参考视角。本书会围绕Kotlin的设计理念,介绍其核心的语言特性,探索它在设计模式、函数式编程、并发等方面的具体应用。
越来越多的公司和团队开始加入Kotlin的阵营。除了Android之外,依靠Kotlin Native等项目,Kotlin也开始在其他领域施展拳脚。在Android官方支持Kotlin之后的数月,Google又推出了Android的Kotlin扩展库,在很大程度上提升了Android开发的体验。Spring 5正式发布时,也将Kotlin作为其主打的新特性之一,使Kotlin再一次受到了很多Web开发者的关注。这一切都预示着这门语言将有无比广阔的前景。
值得注意的是,除了蓬勃发展的生态之外,Kotlin语言本身也在不断迭代。截至本书完稿时,Kotlin又发布了一些有趣的新特性(如inline class),我们对Kotlin的未来充满了期待。
读者对象
Kotlin爱好者
想进阶的Java程序员
对函数式编程感兴趣的读者
Android开发者
开设Java相关课程的大专院校的学生
本书主要内容
本书分为4部分:
第1部分为热身篇—Kotlin基础。介绍Kotlin设计哲学、生态及基础语法。
第2部分为下水篇—Kotlin核心。涉及Kotlin的语言特性,包括面向对象、代数数据类型、模式匹配、类型系统、Lambda、集合、多态、扩展、元编程等方面的知识。其中“代数数据类型和模式匹配”“多态和扩展”在同类书籍中没有过多深入,但笔者认为它们是Kotlin语言中相当重要的特性和应用,故本书中进行了详细介绍探索。
第3部分为潜入篇—Kotlin探索。该部分之所以命名为“探索”,是希望进一步探索Kotlin的设计模式和编程范式,内容包含设计模式、函数式编程、异步和并发编程。其中“函数式编程”为超越Kotlin本身的内容,但可以为读者提供深入理解Kotlin语言特性的示范。
第4部分为遨游篇—Kotlin实战。着重演示Kotlin在Android和Web平台中的应用,包含基于Kotlin的Android架构、开发响应式Web应用。
勘误和支持
由于作者的水平有限,编写时间仓促,书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果你遇到任何问题,或有宝贵意见,欢迎发送邮件至邮箱scala.cool@gmail.com,期待能够得到你们的真挚反馈。
此外,本书所有章节相关的源代码可以通过https://github.com/DiveIntoKotlin进行查看和下载。
致谢
首先感谢程凯先生,他第一时间跟进并审阅了本书大部分稿件,反馈了许多相当宝贵的改进意见。他所在的小余科技是由傅盛投资的创业公司,有着一支非常优秀的Android研发团队。
感谢淘宝飞猪旅行的陈静波先生、依图科技的邵子奇先生、麦多多的创始人古井好月(花名)、工行交易银行中心的季乔卡先生、图讯科技的邹苏启先生、浙江工业大学的蒋博文同学,他们对本书进行了审阅,对内容的纠错和调整提供了很大的帮助。
感谢机械工业出版社华章公司的杨福川老师、孙海亮老师,他们参与了本书的创作,为书籍的策划及写作细节提供了专业的指导,使得本书可充分面向读者、面向市场。
最后,要感谢水滴团队所有参与本书创作的小伙伴们,是大家认真的态度和强大的执行能力促成了本书的出版,他们分别是章建良、单鑫鑫、泮关森、肖宇、汤俞龙、袁国浩。
谨以此书献给所有关注我们ScalaCool团队博客的朋友们,以及众多热爱Kotlin的开发者!
水滴技术团队
目 录 Contents
前言
第4章 代数数据类型和模式匹配85
4.1 代数数据类型85
4.1.1 从代数到类型86
4.1.2 计数87
4.1.3 积类型87
4.1.4 和类型与密封类88
4.1.5 构造代数数据类型89
4.2 模式匹配90
4.2.1 何为模式91
4.2.2 常见的模式92
4.2.3 处理嵌套表达式93
4.2.4 通过Scala找点灵感95
4.2.5 用when力挽狂澜97
4.3 增强 Kotlin 的模式匹配99
4.3.1 类型测试/类型转换99
4.3.2 面向对象的分解100
4.3.3 访问者设计模式102
4.3.4 总结104
4.4 用代数数据类型来抽象业务105
4.4.1 从一个实际需求入手105
4.4.2 糟糕的设计105
4.4.3 利用ADT106
4.4.4 更高层次的抽象108
4.5 本章总结110
第5章 类型系统112
5.1 null引用:10亿美元的错误112
5.1.1 null做了哪些恶112
5.1.2 如何解决NPE问题114
5.2 可空类型115
5.2.1 Java 8中的Optional115
5.2.2 Kotlin的可空类型118
5.2.3 类型检查121
5.2.4 类型智能转换122
5.3 比Java更面向对象的设计124
5.3.1 Any:非空类型的根类型124
5.3.2 Any?:所有类型的根类型127
5.3.3 Nothing与Nothing?128
5.3.4 自动装箱与拆箱128
5.3.5 “新”的数组类型129
5.4 泛型:让类型更加安全130
5.4.1 泛型:类型安全的利刃130
5.4.2 如何在Kotlin中使用泛型131
5.4.3 类型约束:设定类型上界133
5.5 泛型的背后:类型擦除135
5.5.1 Java为什么无法声明一个泛型数组135
5.5.2 向后兼容的罪136
5.5.3 类型擦除的矛盾138
5.5.4 使用内联函数获取泛型139
5.6 打破泛型不变140
5.6.1 为什么List<String>不能赋值给List<Object>140
5.6.2 一个支持协变的List141
5.6.3 一个支持逆变的Comparator143
5.6.4 协变和逆变144
5.7 本章小结147
第6章 Lambda和集合148
6.1 Lambda简化表达148
6.1.1 调用Java的函数式接口148
6.1.2 带接收者的Lambda149
6.1.3 with和apply150
6.2 集合的高阶函数API151
6.2.1 以简驭繁:map151
6.2.2 对集合进行筛选:filter、count152
6.2.3 别样的求和方式:sumBy、sum、fold、reduce154
6.2.4 根据学生性别进行分组:groupBy156
6.2.5 扁平化—处理嵌套集合:flatMap、flatten157
6.3 集合库的设计159
6.3.1 集合的继承关系159
6.3.2 可变集合与只读集合160
6.4 惰性集合163
6.4.1 通过序列提高效率163
6.4.2 序列的操作方式164
6.4.3 序列可以是无限的166
6.4.4 序列与Java 8 Stream对比166
6.5 内联函数167
6.5.1 优化Lambda开销168
6.5.2 内联函数具体语法169
6.5.3 noinline:避免参数被内联171
6.5.4 非局部返回172
6.5.5 crossinline174
6.5.6 具体化参数类型174
6.6 本章小结175
第7章 多态和扩展176
7.1 多态的不同方式176
7.1.1 子类型多态176
7.1.2 参数多态177
7.1.3 对第三方类进行扩展178
7.1.4 特设多态与运算符重载178
7.2 扩展:为别的类添加方法、属性179
7.2.1 扩展与开放封闭原则179
7.2.2 使用扩展函数、属性180
7.2.3 扩展的特殊情况183
7.2.4 标准库中的扩展函数:run、let、also、takeIf186
7.3 Android中的扩展应用188
7.3.1 优化Snackbar188
7.3.2 用扩展函数封装Utils189
7.3.3 解决烦人的findViewById190
7.4 扩展不是万能的193
7.4.1 调度方式对扩展函数的影响193
7.4.2 被滥用的扩展函数196
7.5 本章小结197
第8章 元编程198
8.1 程序和数据199
8.1.1 什么是元编程199
8.1.2 常见的元编程技术201
8.2 Kotlin的反射202
8.2.1 Kotlin和Java反射202
8.2.2 Kotlin的KClass205
8.2.3 Kotlin的KCallable206
8.2.4 获取参数信息208
8.3 Kotlin的注解210
8.3.1 无处不在的注解211
8.3.2 精确控制注解的位置212
8.3.3 获取注解信息213
8.4 本章小结216
潜入篇 Kotlin探索
第9章 设计模式218
9.1 创建型模式218
9.1.1 伴生对象增强工厂模式219
9.1.2 内联函数简化抽象工厂222
9.1.3 用具名可选参数而不是构建者模式224
9.2 行为型模式228
9.2.1 Kotlin中的观察者模式228
9.2.2 高阶函数简化策略模式、模板方法模式231
9.2.3 运算符重载和迭代器模式235
9.2.4 用偏函数实现责任链模式237
9.2.5 ADT实现状态模式241
9.3 结构型模式244
9.3.1 装饰者模式:用类委托减少样板代码245
9.3.2 通过扩展代替装饰者246
9.4 本章小结248
第10章 函数式编程249
10.1 函数式编程的特征249
10.1.1 函数式语言之争250
10.1.2 纯函数与引用透明性251
10.1.3 代换模型与惰性求值253
10.2 实现Typeclass254
10.2.1 高阶类型:用类型构造新类型255
10.2.2 高阶类型和Typeclass256
10.2.3 用扩展方法实现Typeclass257
10.2.4 Typeclass设计常见功能258
10.3 函数式通用结构设计262
10.3.1 Monoid262
10.3.2 Monad264
10.3.3 Monad组合副作用269
10.4 类型代替异常处理错误271
10.4.1 Option与OptionT272
10.4.2 Either与EitherT276
10.5 本章小结279
第11章 异步和并发281
11.1 同步到异步281
11.1.1 同步与阻塞的代价281
11.1.2 利用异步非阻塞来提高效率284
11.1.3 回调地狱284
11.2 Kotlin的Coroutine286
11.2.1 多线程一定优于单线程吗287
11.2.2 协程:一个更轻量级的“线程”287
11.2.3 合理地使用协程288
11.2.4 用同步方式写异步代码290
11.3 共享资源控制293
11.3.1 锁模式293
11.3.2 Actor:有状态的并行计算单元296
11.4 CQRS架构302
11.4.1 Event Sourcing事件溯源—记录对象操作轨迹302
11.4.2 Kotlin with Akka Persistence-Actor304
11.5 本章小结310
遨游篇 Kotlin实战
第12章 基于Kotlin的Android架构314
12.1 架构方式的演变314
12.1.1 经典的 MVC 问题315
12.1.2 MVP316
12.1.3 MVVM320
12.2 单向数据流模型327
12.2.1 Redux327
12.2.2 单向数据流的优势329
12.3 ReKotlin331
12.3.1 初见 ReKotlin331
12.3.2 创建基于ReKotlin的项目332
12.4 解耦视图导航341
12.4.1 传统导航的问题341
12.4.2 rekotlin-router342
12.5 本章小结343
第13章 开发响应式Web应用345
13.1 响应式编程的关键:非阻塞异步编程模型345
13.1.1 使用CompletableFuture实现异步非阻塞346
13.1.2 使用RxKotlin进行响应式编程347
13.1.3 响应式Web编程框架348
13.2 Spring 5:响应式Web框架349
13.2.1 支持响应式编程349
13.2.2 适配Kotlin350
13.2.3 函数式路由351
13.2.4 异步数据库驱动353
13.3 Spring 5响应式编程实战354
13.4 本章小结360
- 点赞
- 收藏
- 关注作者
评论(0)