目录 第一部分入门 第1章第一个Kotlin应用程序 1.1安装IntelliJ IDEA 1.2第一个Kotlin项目 1.2.1创建第一个Kotlin文件 1.2.2运行Kotlin文件 1.2.3Kotlin/JVM代码的编译和执行 1.3Kotlin REPL 1.4好奇之处: 为什么使用IntelliJ 1.5好奇之处: 面向JVM 1.6挑战之处: REPL算术运算 第2章变量、常量和类型 2.1类型 2.2声明变量 2.3Kotlin的内置类型 2.4只读变量 2.5类型推断 2.6编译时常量 2.7检查Kotlin字节码 2.8好奇之处: Kotlin中的Java基本类型 2.9挑战之处: hasSteed 2.10挑战之处: The Unicorns Horn酒吧 2.11挑战之处: 魔镜 第二部分基本语法 第3章条件判断 3.1if/else语句 3.2区间 3.3when表达式 3.4挑战之处: 灵活使用区间 第4章函数 4.1将代码提炼为函数 4.2函数剖析 4.3函数调用 4.4自定义函数 4.5默认实际参数 4.6单表达式函数 4.7Unit函数 4.8命名函数的实际参数 4.9好奇之处: Nothing类型 4.10好奇之处: Java中的文件级函数 4.11好奇之处: 函数重载 4.12好奇之处: 反引号中的函数名 第5章数值 5.1数值类型 5.2整数 5.3浮点数 5.4格式化双精度数值 5.5在数值类型之间进行转换 5.6好奇之处: 无符号数 5.7好奇之处: 位运算 第6章字符串 6.1字符串插值 6.2原始字符串 6.3从控制台读取输入 6.4将字符串转换为数值 6.5正则表达式 6.6字符串操作 6.7字符串比较 6.8好奇之处: Unicode 第7章空安全和异常处理 7.1Nullability 7.2Kotlin的显式Null类型 7.3编译时和运行时 7.4空安全 7.4.1选项1: 使用if语句检查null值 7.4.2选项2: 安全调用运算符 7.4.3选项3: nonnull断言运算符 7.5异常 7.5.1抛出异常 7.5.2异常处理 7.5.3try/catch表达式 7.6前置条件 7.7好奇之处: 自定义异常 7.8好奇之处: 已检查的异常和未检查的异常 第三部分函数式编程和Collection 第8章Lambda表达式和函数类型 8.1NyetHack简介 8.2匿名函数 8.3Lambda表达式 8.3.1函数类型 8.3.2隐式返回值 8.3.3函数的实际参数 8.3.4it标识符 8.3.5接收多个实际参数 8.4类型推断支持 8.5更有效的Lambda 8.6定义一个以函数为参数的函数 8.7函数内联 8.8Lambda和Kotlin标准库 8.9有趣之处: 函数引用 8.10好奇之处: 捕获Lambda 8.11挑战之处: 新头衔和新情绪 第9章List和Set 9.1List 9.1.1访问List中的元素 9.1.2更改List中的内容 9.2重复迭代 9.3将文件读入List中 9.4解构化 9.5Set 9.5.1创建一个Set 9.5.2向Set中添加元素 9.6while循环 9.7Collection之间的转换 9.8有趣之处: Array类型 9.9好奇之处: 只读的与不可变的 9.10好奇之处: break表达式 9.11好奇之处: Return标签 9.12挑战之处: 格式化的酒馆菜单 9.13挑战之处: 更高级的格式化酒馆菜单 第10章Map 10.1创建一个Map 10.2访问Map的值 10.3向Map中添加条目 10.4修改Map的值 10.5在List与Map之间进行转换 10.6在Map中迭代 10.7挑战之处: 复杂的订单 第11章函数式编程基础 11.1转换数据 11.1.1map()函数 11.1.2associate()函数 11.1.3使用函数式编程进行解构 11.1.4flatMap()函数 11.1.5map()函数 vs flatMap()函数 11.2过滤数据 11.3组合函数 11.4为什么选择函数式编程 11.5Sequence 11.6好奇之处: 性能分析 11.7好奇之处: 聚合数据 11.7.1reduce()函数 11.7.2fold()函数 11.7.3SumBy()函数 11.8好奇之处: 关键字vararg 11.9好奇之处: Arrow.kt 11.10挑战之处: 翻转Map中的值 11.11挑战之处: 找出最喜爱的商品 第12章作用域函数 12.1apply()函数 12.2let()函数 12.3run()函数 12.4with()函数 12.5also()函数 12.6takeIf()函数 12.7使用作用域函数 第四部分面向对象编程 第13章类 13.1定义类 13.2构建实例 13.3类函数 13.4可见性和封装 13.5类属性 13.6使用软件包 13.7好奇之处: 详细解析var和val属性 13.8好奇之处: 防止可变性 13.9好奇之处: Package Private 第14章初始化 14.1构造函数 14.1.1主构造函数 14.1.2在主构造函数中定义属性 14.1.3次构造函数 14.1.4默认实际参数 14.1.5命名实际参数 14.2初始化程序块 14.3初始化顺序 14.4延迟初始化 14.4.1后期初始化 14.4.2惰性初始化 14.5好奇之处: 初始化陷阱 14.6好奇之处: 属性代理 14.7挑战之处: 圣剑Excalibur之谜 第15章继承 15.1定义room类 15.2创建一个子类 15.3类型检查 15.4Kotlin的类型层次结构 15.4.1类型强制转换 15.4.2智能强制转换 15.5重构酒馆 15.6好奇之处: Any类 15.7好奇之处: 安全的强制转换运算符 第16章对象、数据类和枚举类 16.1对象关键字 16.1.1对象声明 16.1.2对象表达式 16.1.3伴生对象 16.2嵌套类 16.3数据类 16.3.1toString()函数 16.3.2equals()函数和hashCode()函数 16.3.3Copy()函数 16.3.4解构声明 16.4枚举类 16.5运算符重载 16.6探索NyetHack的世界 16.7好奇之处: 定义结构比较 16.8好奇之处: 代数数据类型 16.9好奇之处: 值类 16.10挑战之处: 更多的命令 16.11挑战之处: 实现一个游戏世界地图 16.12挑战之处: 敲响钟声 第17章接口和抽象类 17.1定义接口 17.2实现接口 17.3默认实现 17.4抽象类 17.5在NyetHack中进行战斗 17.6挑战之处: 更多的怪物 第五部分高级Kotlin 第18章泛型 18.1定义泛型类型 18.2泛型函数 18.3泛型约束 18.4in和out 18.5添加Loot至NyetHack 18.6好奇之处: 关键字reified 第19章扩展 19.1定义扩展函数 19.1.1在超类上定义一个扩展函数 19.1.2通用扩展函数 19.1.3运算符扩展函数 19.2扩展属性 19.3对Nullable类型的扩展 19.4扩展的实现原理 19.5扩展的可见性 19.6Kotlin标准库中的扩展 19.7好奇之处: 带有接收器的函数字面量 19.8挑战之处: 框架扩展 第20章协程 20.1阻塞调用 20.2启用协程 20.3协程构建器 20.4协程作用域 20.5结构化并发 20.6使用HTTP客户端 20.7async和await 20.8好奇之处: 竞态条件 20.9好奇之处: 服务器端Kotlin 20.10挑战之处: 不允许取消 第21章流 21.1设置流 21.2MutableStateFlow 21.3流终止 21.4流转换 21.5流中的错误处理 21.6好奇之处: SharedFlow 第22章通道 22.1使用通道对工作进行拆分 22.2发送至通道 22.3从通道中接收 22.4关闭通道 22.5加入jobs 22.6好奇之处: 其他的通道行为 22.6.1会合通道 22.6.2缓冲通道 22.6.3无限制通道 22.6.4合并通道 第六部分互操作和跨平台应用 第23章Java互操作性 23.1与Java类进行交互 23.2互操作性和Nullity 23.3类型映射 23.4Getter、Setter和互操作性 23.5超越类 23.6异常和互操作性 23.7Java中的函数类型 第24章Kotlin跨平台简介 24.1什么是Kotlin跨平台 24.2规划跨平台项目 24.3第一个跨平台项目 24.4定义Kotlin/JVM平台 24.5定义共享代码 24.6expect和actual 第25章Kotlin/Native 25.1声明一个macOS平台 25.2使用Kotlin编写本机代码 25.3启动一个Kotlin/Native应用程序 25.4Kotlin/Native输出 25.5好奇之处: Kotlin移动跨平台 25.6好奇之处: 其他本机平台 第26章Kotlin/JS 26.1宣布对Kotlin/JS的支持 26.2与DOM进行交互 26.3关键字external 26.4执行原始的JavaScript 26.5Dynamic类型 26.6好奇之处: 前端框架 26.7挑战之处: 货币兑换费 第27章后记 27.1展望 27.2宣传 27.3致谢