《Kotlin 实战》将从语言的基本特性开始,逐渐覆盖其更多的高级特性,尤其注重讲解如何将 Koltin 集成到已有 Java 工程实践及其背后的原理。本书分为两个部分。部分讲解如何开始使用 Kotlin 现有的库和API,包括基本语法、扩展函数和扩展属性、数据类和伴生对象、lambda 表达式,以及数据类型系统(着重讲解了可空性和集合的概念)。第二部分教你如何使用 Kotlin 构建自己的 API,以及一些深层次特性——约定和委托属性、高阶函数、泛型、注解和反射,以及领域特定语言的构建。《Kotlin 实战》适合广大移动开发者及入门学习者,尤其是紧跟主流趋势的前沿探索者。
《Kotlin 实战》教会你使用 Kotlin 语言来开发达到产品级品质的应用。《Kotlin 实战》为具备一定 Java 经验的开发者编写,包含了丰富的示例,和大多数介绍编程语言的书籍相比更加深入,涵盖了非常有趣的话题,例如怎样构建使用自然语言语法的 DSL。两位作者是 Kotlin 的核心开发者,所以你可以相信书中细枝末节的内容都无比地。
● 在 JVM 上进行函数式编程
● 编写整洁并符合语义习惯的代码
● 结合运用 Kotlin 和 Java
● 领域特定语言
作者简介
本书作者为 JetBrains 的 Kotlin 核心开发者!Dmitry Jemerov 从2003年起就在 JetBrains ?作并参与了许多产品的开发,包括IntelliJ IDEA、PyCharm 和 WebStorm。他是 Kotlin 最早的贡献者之?,创建了最初版本的 Kotlin JVM 字节码?成器,并且还在世界各地的活动上做了很多关于 Kotlin 的演示。?前他带领了进? Kotlin IntelliJ IDEA 插件开发的团队。
Svetlana Isakova 从2011年成为 Kotlin 团队的?员。她从事编译器类型推导和重载解析?系统的?作。现在她是?名技术布道者,在各种会议上进? Kotlin 相关讨论并从事 Kotlin 在线课程的相关?作。
译者简介
覃宇,ThoughtWorks 高级咨询师,10余年移动应用开发经验,Android 技术专家,曾为AOSP贡献过测试用例;目前专注于移动应用的架构设计、自动化测试以及持续交付。
罗丽,高级软件工程师,移动技术开发顾问,拥有丰富的软件开发经验, 熟悉React Native,Android,iOS等多种开发技术。目前任职于ThoughtWorks海外事业部,曾在多个大型移动应用项目中担任技术顾问。
李思阳,ThoughtWorks咨询师,移动开发工程师。熟悉Android、Mobile Web相关技术,有着丰富的移动应用开发经验,在移动应用体验和兼容性相关领域有独特的见解;长期关注Android领域相关技术动向。
蒋扬海,ThoughtWorks移动开发咨询师,深耕Android开发多年,应用开发经验丰富,对Android开发领域的技术有广泛的涉猎,对Android技术动向有着敏锐的洞察力。
第 1 部分 Kotlin 简介 1
1 Kotlin :定义和目的 3
1.1Kotlin 初体验 3
1.2Kotlin 的主要特征4
1.2.1目标平台 :服务器端、Android 及任何 Java 运行的地方 4
1.2.2静态类型5
1.2.3函数式和面向对象 6
1.2.4免费并开源 7
1.3Kotlin 应用8
1.3.1服务器端的 Kotlin8
1.3.2Android 上的 Kotlin 9
1.4Kotlin 的设计哲学 10
1.4.1务实10
1.4.2简洁 11
1.4.3安全12
1.4.4互操作性 13
1.5使用 Kotlin 工具 14
1.5.1编译 Kotlin 代码 14
1.5.2IntelliJ IDEA 和 Android Studio 插件 15
1.5.3交互式 shell15
1.5.4Eclipse 插件 15
1.5.5在线 playground 15
1.5.6Java 到 Kotlin 的转换器 16
1.6小结16
2 Kotlin 基础 17
2.1基本要素 :函数和变量 17
2.1.1Hello,world!18
2.1.2函数18
2.1.3变量20
2.1.4更简单的字符串格式化 :字符串模板 22
2.2类和属性 23
2.2.1属性24
2.2.2自定义访问器 25
2.2.3Kotlin 源码布局 :目录和包26
2.3表示和处理选择 :枚举和“when” 28
2.3.1声明枚举类28
2.3.2使用“when”处理枚举类 29
2.3.3在“when”结构中使用任意对象 30
2.3.4使用不带参数的“when” 31
2.3.5智能转换 :合并类型检查和转换32
2.3.6重构 :用“when”代替“if” 34
2.3.7代码块作为“if”和“when”的分支 35
2.4迭代事物 :“while”循环和“for”循环 36
2.4.1“while”循环36
2.4.2迭代数字 :区间和数列 37
2.4.3迭代 map 38
2.4.4使用“in”检查集合和区间的成员39
2.5Kotlin 中的异常 41
2.5.1“try”“catch”和“finally” 41
2.5.2“try”作为表达式 42
2.6小结44
3 函数的定义与调用 45
3.1在 Kotlin 中创建集合 45
3.2让函数更好调用 47
3.2.1命名参数 48
3.2.2默认参数值49
3.2.3消除静态工具类 :顶层函数和属性 50
3.3给别人的类添加方法 :扩展函数和属性53
3.3.1导入和扩展函数 54
3.3.2从 Java 中调用扩展函数54
3.3.3作为扩展函数的工具函数55
3.3.4不可重写的扩展函数 56
3.3.5扩展属性 58
3.4处理集合 :可变参数、中缀调用和库的支持 59
3.4.1扩展 Java 集合的 API 59
3.4.2可变参数 :让函数支持任意数量的参数60
3.4.3键值对的处理 :中缀调用和解构声明 60
3.5字符串和正则表达式的处理 62
3.5.1分割字符串62
3.5.2正则表达式和三重引号的字符串63
3.5.3多行三重引号的字符串 64
3.6让你的代码更整洁 :局部函数和扩展 66
3.7小结68
4 类、对象和接口 69
4.1定义类继承结构 70
4.1.1Kotlin 中的接口 70
4.1.2open、final 和 abstract 修饰符 :默认为 final72
4.1.3可见性修饰符 :默认为 public 75
4.1.4内部类和嵌套类 :默认是嵌套类76
4.1.5密封类 :定义受限的类继承结构79
4.2声明一个带非默认构造方法或属性的类80
4.2.1初始化类 :主构造方法和初始化语句块80
4.2.2构造方法 :用不同的方式来初始化父类83
4.2.3实现在接口中声明的属性85
4.2.4通过 getter 或 setter 访问支持字段 87
4.2.5修改访问器的可见性 88
4.3编译器生成的方法 :数据类和类委托 89
4.3.1通用对象方法 89
4.3.2数据类 :自动生成通用方法的实现 92
4.3.3类委托 :使用“by”关键字 93
4.4“object”关键字 :将声明一个类与创建一个实例结合起来95
4.4.1对象声明 :创建单例易如反掌 95
4.4.2伴生对象 :工厂方法和静态成员的地盘98
4.4.3作为普通对象使用的伴生对象 100
4.4.4对象表达式 :改变写法的匿名内部类 102
4.5小结 104
5 Lambda 编程 105
5.1Lambda 表达式和成员引用 105
5.1.1Lambda 简介 :作为函数参数的代码块106
5.1.2Lambda 和集合 107
5.1.3Lambda 表达式的语法 108
5.1.4在作用域中访问变量 111
5.1.5成员引用 114
5.2集合的函数式 API 116
5.2.1基础 :filter 和 map 116
5.2.2“all”“any”“count”和“find”: 对集合应用判断式 118
5.2.3groupBy :把列表转换成分组的 map 119
5.2.4flatMap 和 flatten :处理嵌套集合中的元素120
5.3惰性集合操作 :序列121
5.3.1执行序列操作 :中间和末端操作 123
5.3.2创建序列 125
5.4使用 Java 函数式接口 126
5.4.1把 lambda 当作参数传递给 Java 方法127
5.4.2SAM 构造方法 :显式地把 lambda 转换成函数式接口 129
5.5带接收者的 lambda :“with”与“apply”131
5.5.1“with”函数131
5.5.2“apply”函数 133
5.6小结 135
6 Kotlin 的类型系统137
6.1可空性137
6.1.1可空类型 138
6.1.2类型的含义 140
6.1.3安全调用运算符 :“?:”141
6.1.4Elvis 运算符 :“?:” 143
6.1.5安全转换 :“as?” 145
6.1.6非空断言 :“!!”146
6.1.7“let”函数148
6.1.8延迟初始化的属性 149
6.1.9可空类性的扩展 151
6.1.10类型参数的可空性 153
6.1.11可空性和 Java 153
6.2基本数据类型和其他基本类型 157
6.2.1基本数据类型 :Int、Boolean 及其他158
6.2.2可空的基本数据类型 :Int?、Boolean? 及其他159
6.2.3数字转换 160
6.2.4“Any”和“Any?”:根类型 162
6.2.5Unit 类型 :Kotlin 的“void”163
6.2.6Nothing 类型 :“这个函数永不返回” 164
6.3集合与数组 164
6.3.1可空性和集合165
6.3.2只读集合与可变集合167
6.3.3Kotlin 集合和 Java 168
6.3.4作为平台类型的集合171
6.3.5对象和基本数据类型的数组173
6.4小结 175
第 2 部分 拥抱 Kotlin 177
7 运算符重载及其他约定179
7.1重载算术运算符 180
7.1.1重载二元算术运算 180
7.1.2重载复合赋值运算符183
7.1.3重载一元运算符 184
7.2重载比较运算符 186
7.2.1等号运算符 :“equals" 186
7.2.2排序运算符 :compareTo187
7.3集合与区间的约定 188
7.3.1通过下标来访问元素 :“get”和“set” 188
7.3.2“in”的约定190
7.3.3rangeTo 的约定 191
7.3.4在“for”循环中使用“iterator”的约定 192
7.4解构声明和组件函数193
7.4.1解构声明和循环 194
7.5重用属性访问的逻辑 :委托属性 195
7.5.1委托属性的基本操作196
7.5.2使用委托属性 :惰性初始化和“by lazy()”197
7.5.3实现委托属性198
7.5.4委托属性的变换规则202
7.5.5在 map 中保存属性值 203
7.5.6框架中的委托属性 204
7.6小结 205
8 高阶函数 :Lambda 作为形参和返回值 207
8.1声明高阶函数207
8.1.1函数类型 208
8.1.2调用作为参数的函数209
8.1.3在 Java 中使用函数类 211
8.1.4函数类型的参数默认值和 null 值 212
8.1.5返回函数的函数 214
8.1.6通过 lambda 去除重复代码 216
8.2内联函数 :消除 lambda 带来的运行时开销218
8.2.1内联函数如何运作 219
8.2.2内联函数的限制 221
8.2.3内联集合操作222
8.2.4决定何时将函数声明成内联223
8.2.5使用内联 lambda 管理资源 223
8.3高阶函数中的控制流225
8.3.1lambda 中的返回语句 :从一个封闭的函数返回225
8.3.2从 lambda 返回 :使用标签返回226
8.3.3匿名函数 :默认使用局部返回 228
8.4小结 229
9 泛型 231
9.1泛型类型参数232
9.1.1泛型函数和属性 232
9.1.2声明泛型类 234
9.1.3类型参数约束235
9.1.4让类型形参非空 237
9.2运行时的泛型 :擦除和实化类型参数 238
9.2.1运行时的泛型 :类型检查和转换 238
9.2.2声明带实化类型参数的函数241
9.2.3使用实化类型参数代替类引用 243
9.2.4实化类型参数的限制244
9.3变型 :泛型和子类型化 245
9.3.1为什么存在变型 :给函数传递实参245
9.3.2类、类型和子类型 246
9.3.3协变 :保留子类型化关系 248
9.3.4逆变 :反转子类型化关系 252
9.3.5使用点变型 :在类型出现的地方指定变型254
9.3.6星号投影 :使用 代替类型参数 257
9.4小结 261
10 注解与反射 263
10.1声明并应用注解264
10.1.1应用注解264
10.1.2注解目标265
10.1.3使用注解定制 JSON 序列化 267
10.1.4声明注解269
10.1.5元注解 :控制如何处理一个注解 270
10.1.6使用类做注解参数 271
10.1.7使用泛型类做注解参数272
10.2反射 :在运行时对 Kotlin 对象进行自省 273
10.2.1Kotlin 反射 API :KClass、KCallable、KFunction 和KProperty 274
10.2.2用反射实现对象序列化278
10.2.3用注解定制序列化 279
10.2.4JSON 解析和对象反序列化283
10.2.5反序列化的一步 :callBy() 和使用反射创建对象 287
10.3小结 291
11 DSL 构建 293
11.1从 API 到 DSL 293
11.1.1领域特定语言的概念 295
11.1.2内部 DSL296
11.1.3DSL 的结构 297
11.1.4使用内部 DSL 构建 HTML298
11.2构建结构化的 API:DSL 中带接收者的 lambda 299
11.2.1带接收者的 lambda 和扩展函数类型 299
11.2.2在 HTML 构建器中使用带接收者的 lambda 303
11.2.3Kotlin 构建器 :促成抽象和重用307
11.3使用“invoke”约定构建更灵活的代码块嵌套 310
11.3.1“invoke”约定 :像函数一样可以调用的对象 310
11.3.2“invoke”约定和函数式类型 311
11.3.3DSL 中的“invoke”约定 :在 Gradle 中声明依赖 312
11.4实践中的 Kotlin DSL 314
11.4.1把中缀调用链接起来 :测试框架中的“should” 314
11.4.2在基本数据类型上定义扩展 :处理日期 316
11.4.3成员扩展函数 :为 SQL 设计的内部 DSL317
11.4.4Anko :动态创建 Android UI 320
11.5小结 322
A 构建 Kotlin 项目 323
B Kotlin 代码的文档化 327
C Kotlin 生态系统 331
译者序
当收到这本书的翻译邀请时,我们的内心是激动的,终于有机会将自己喜爱的语言系统地介绍给中国的开发者,而且是通过口碑颇佳的实战系列。此时,正值2017 年度的 Google I/O 召开前夕,接下来重磅消息大家都知道了 :在 Google I/O 大会上,Kotlin 正式成为了官方的 Android 开发语言,迅速占据了国内各大技术媒体的头条。一夜之间,所有的 Android 开发者都迫切地想搞清楚它的来龙去脉。Kotlin究竟是何方神圣,为什么是它?
这一点儿也不奇怪。对于博学 Android 开发者来说,Kotlin 早已不是新鲜的概念了。早在 2015 年 1 月,Android 开发者社区大神 Jake Wharton 就了一篇使用Kotlin 来进行 Android 开发的总结。那时开始,不少顶尖的开发者和公司就开始尝试在正式的 Android 项目中使用 Kotlin 语言 ;我们也从 2015 年开始在多个项目上使用了 Kotlin 语言。它带给我们的体验,和带给所有其他实践过 Kotlin 语言的开发者的一样 :它的发明者 JetBrains 所言非虚,这是一门简洁、安全、实用的语言,用了就停不下来,就忍不住地想推荐给周围的人。我们理所当然地把 Kotlin 放在了今年及时季度 ThoughtWorks 技术雷达的评估象限 :https://www.thoughtworks.com/radar/languages-and-frameworks/kotlin。
Kotlin 让人爱不释手的最重要原因就是来自 JetBrains 的基因。作为最负盛名的IDE 创造者,JetBrains 深谙开发者的需求,孜孜不倦地追求给开发者提供最实用、较高效的 IDE,包括 Android Studio、IntelliJ、RubyMine 等。由这样想开发者之所想的公司创造出来的语言,又怎么会不受开发者热捧呢?所以 Gradle、Spring,以及越来越多的库、框架和工具也陆续加入到了支持 Kotlin 的阵营。
本书深入浅出地介绍了 Kotlin 语言的方方面面,从最基础的语言要素到如何定制自己的 DSL 都有涉及。相信读者阅读本书并尝试之后一定会爱上这门语言,但把 Kotlin 应用到自己的项目中会不会有什么风险呢?读者们大可不必担心,以往的经验告诉我们,整个过程无缝无痛。首先,Kotlin 足够简单,对于初学者来说掌握也不算困难,两三天就可以上手 ;其次,Kotlin 和 Java 可以无缝地衔接,可以在遗留项目上和 Java 混用 ;,编译器的静态检查和 IDE(必须是 JetBrains 出品的 IntelliJ IDEA 或者 Android Studio)强大的辅助功能,可以帮你发现很多问题(例如空指针异常)并将其自动消除在摇篮之中。有的读者会说,但我还没有用过这些IDE 啊?那你还在犹豫什么,请立即使用它们来提高你的生产力吧!这也算是使用Kotlin 带来的额外收获。
从 Kotlin 成为 Android 开发语言的那一刻开始,我们热情高涨地投入了几乎全部业余时间到本书的翻译工作,终于在最短的时间内把它呈现在广大读者面前。这一切还要感谢本书的编辑和所有译者家人在背后的默默付出。由于译者水平所限,难免出现谬误遗漏,还望读者海涵斧正。
覃宇、罗丽、李思阳、蒋扬海
2017 年 6 月于 ThoughtWorks 成都
序
当我在 2010 年春季及时次拜访 JetBrains 的时候,我相当确定世界上不需要另一种通用编程语言了。我认为现有的 JVM 上的语言已经足够好了,谁会有想法去创建一门新语言呢?在经过大约一个小时的关于大规模代码库上产品问题的讨论后我被说服了,并且后来成为 Kotlin 一部分的最初想法就已经被描绘在白板上。很快我就加入了 JetBrains 来主导这门语言的设计与编译器的开发工作。
到今天,六年多的时光过去了,我们也快要第二个版本。我们已经拥有超过 30 人的团队和数以千计的活跃用户,还有很多让我们难以轻易实现的精彩的设计理念。但是不要担心,这些想法在进入这门语言之前还必须经过缜密的考察。我们希望这本书的篇幅依然能够容得下 Kotlin 的未来。
学习一门编程语言是一个令人兴奋而且常常是回报颇丰的尝试。如果它是你的及时门语言,通过它你能学到整个编程的新世界。如果不是,它会使你以新的术语来思考熟悉的东西,从而以更高层次的抽象来更深入地了解它们。本书主要针对后者,即面向已经熟悉 Java 的读者。
从头开始设计一门语言可能是一项具有挑战性的任务,但是使其与另一门语言融洽的工作就是另一回事了——尤其是那门语言还包含了许多的愤怒的食人魔,以及一些阴暗的地牢(在这一点上你如果不相信可以去问 C 的创造者 Bjarne Stroustrup)。与 Java 的互操作性(这就是 Java 与 Kotlin 之间是如何互相混合调用的)是 Kotlin 的基石之一,本书也投入了很多的注意力在这一点上。互操作性对于在一个已有的 Java 代码库中逐步地引入 Kotlin 非常重要。即使从头开始开发一个新项目时,也必须考虑到能够将这门语言融入一个拥有更大图景的平台中去,而以 Java 编写的所有函数库就是这样的一个平台。
当我在编写本书时,两个新的目标平台正在开发 :Kotlin 现在可以在 JavaScript虚拟机上运行以支持全栈 web 开发,并且还将很快能够直接编译成原生代码,从而在需要的时候能够脱离任何的虚拟机来运行。 1 所以,虽然本书是面向 JVM 的,但是你从中学到的很多东西也是可以应用于其他运行环境的。
本书作者从项目伊始就已经是 Kotlin 团队的成员,所以他们对语言本身和内部实现非常熟悉。他们在会议演讲、研讨会及 Kotlin 课程方面的经验使他们能够对预期的常见问题及可能的陷阱,提供良好的阐述。本书既阐释了语言特征背后的高级概念,也提供了足够深入的细节。
希望你能享受与我们的语言及本书相处的时光。正如我经常在我们社区的帖子中说的那样 :使用 Kotlin 愉快!
ANDREY BRESLAV,JetBrains Kotlin 首席设计师
开发者想完成他们的工作——同时越省事越好。使用 Kotlin 编码就意味着省事。Kotlin 编程语言提供了赋有表现力的语法,强大直观的类型系统和美妙的工具支持,还有与现存 Java 代码、库及框架无缝的互操作性。Kotlin 可以被编译成 Java 字节码,所以你可以在所有使用 Java 的地方使用它,包括 Android 在内。借助高效的编译器和标准库,Kotlin 在运行时几乎不用承受任何额外开销。
——kotlin核心开发者
“既阐释了高级概念,也提供了足够深入的细节。”
— 摘自 Kotlin 首席设计师 Andrey Breslav 作的序
“这本书保持了 Manning 实战系列的水准,满足了你快速提高生成力的所有需要。”
— Kevin Orr, Sumus Solutions
“有这本书指导你,Kotlin 学起来有趣又简单!”
— Filip Pravica, Info.nl
“写得非常,非常好,浅显易懂。”
— Jason Lee, NetSuite
这书可以,好好学习
我很喜欢新事物
好书,印刷清晰内容强!我喜欢
纸张还行 主要是送货快
非常好,入门kotlin就靠它了,很棒
不错正品 值得买,包装也挺好的,这个价钱值了
已经开始看了,加油。
很好,学习无止境,程序猿!
书还不错。
很有帮助,学到了很多
书就不多说了,当当也是专门卖书的电商,每次在当当卖书都是一个塑料袋套书。运输过程中各种暴力。主皮被不明尖物体扎了两个眼,另一本书角明显是被暴力仍后落地,书角都仍嘿了。包装差评差评差评
新技术,赶紧买一本看看
很好!快递员也很好,速度很快
经典之作,学习Kotlin的好书
不错,没破损
帮朋友买的,用来自学。
这本书还不错
常阅可修身养性可陶冶性情可励志也是我们洞察世界的途径现实一点说就是古人说的
111111
还没看,中文版就这一本,先买着有时间学习一下