Kotlin 核心编程 (32):基础语法 2.4.1

阅读数:2 2019 年 12 月 25 日 15:33

Kotlin核心编程(32):基础语法 2.4.1

(表达式比语句更安全)

内容简介
本书不是一本简单介绍 Kotlin 语法应用的图书,而是一部专注于帮助读者深入理解 Kotlin 的设计理念,指导读者实现 Kotlin 高层次开发的实战型著作。书中深入介绍了 Kotlin 的核心语言特性、设计模式、函数式编程、异步开发等内容,并以 Android 和 Web 两个平台为背景,演示了 Kotlin 的实战应用。
全书共 13 章,分为 4 个部分:
热身篇—Kotlin 基础(第 1~2 章),简单介绍了 Kotlin 设计哲学、生态及基础语法,其中包括 Kotlin 与 Scala、Java 之间的关联与对比,以及 Kotlin 的类型声明的特殊性、val 和 var 的使用、高阶函数的使用、面向表达式编程的使用、字符串的定义与操作等内容;
下水篇—Kotlin 核心(第 3~8 章),深入介绍了面向对象、代数数据类型、模式匹配、类型系统、Lambda、集合、多态、扩展、元编程等 Kotlin 开发核心知识,这是本书的重点,其中涉及很多开发者特别关心的问题,比如多继承问题、模式匹配问题、用代数数据类型抽象业务问题、泛型问题、反射问题等。
潜入篇—Kotlin 探索(第 9~11 章),探索 Kotlin 在设计模式、函数式编程、异步和并发等编程领域的应用,其中包括对 4 大类设计模式、Typeclass 实现、函数式通用结构设计、类型替代异常处理、共享资源控制、CQRS 架构等重点内容的深入剖析;
遨游篇—Kotlin 实战(第 12~13 章),着重演示了 Kotlin 在 Android 和 Web 平台的实战案例,其中涉及架构方式、单向数据流模型、解耦视图导航、响应式编程、Spring 5 响应式框架和编程等内容。

我们先来写一段 Java 代码。刚开始我们还是采用熟悉的 if 语句用法:

复制代码
void ifStatement(Boolean flag) {
String a = null;
if (flag) {
a = "dive into kotlin";
}
System.out.println(a.toUpperCase());
}

非常简单的代码,由于 if 在这里不是一个表达式,所以我们只能够在外部对变量 a 进行声明。仔细思考一下,这段代码存在潜在的问题:

  • a 必须在 if 语句外部声明,它被初始化为 null。这里的 if 语句的作用就是对 a 进行赋值,这是一个副作用。在这个例子中,我们忽略了 else 分支,如果 flag 的条件判断永远为 true,那么程序运行并不会出错;否则,将会出现“java.lang.NullPointerException”的错误,即使程序依旧会编译通过。因此,这种通过语句创建副作用的方式很容易引发 bug。
  • 继续思考,现在的逻辑虽然简单,然而如果变量 a 来自上下文其他更远的地方,那么这种危险会更加容易被忽视。典型的例子就是一段并发控制的程序,业务开发会变得非常不安全。

接下来,我们再来创建一个 Kotlin 的版本,现在 if 会被作为表达式来使用:

复制代码
fun ifExpression(flag: Boolean) {
val a = if (flag) "dive into Kotlin" else ""
println(a.toUpperCase())
}

下面分析 Kotlin 的版本:

  • 表达式让代码变得更加紧凑了。我们可以把赋值语句与 if 表达式混合使用,就不存在变量 a 没有初始值的情况。
  • 在 if 作为表达式时,else 分支也必须被考虑,这很容易理解,因为表达式具备类型信息,最终它的类型就是 if、else 多个分支类型的相同类型或公共父类型。

可以看出,基于表达式的方案彻底消除了副作用,让程序变得更加安全。当然,这并不是说表达式不会有副作用,实际上我们当然可以用表达式写出带有副作用的语句,就像这样子:

复制代码
var a = 1
fun foo() = if (a > 0) {
a = 2 // 副作用,a 的值变化了
a
} else 0

然而从设计角度而言,语句的作用就是服务于创建副作用的,相比较表达式的目的则是为了创造新值。在函数式编程中,原则上表达式是不允许包含副作用的。

一切皆表达式
撇开 Haskell 不谈,在一些极力支持函数式编程的语言中,比如 Scala 和 F#,即使它们不是纯函数式语言,也都实现了一个特性,即一切皆表达式。一切皆表达式的设计让开发者在设计业务时,促进了避免创造副作用的逻辑设计,从而让程序变得更加安全。

由于把百分之百兼容 Java 作为设计目标,Kotlin 并没有采纳一切皆表达式的设计,然而它在 Java 的基础上也在很大程度上增强了这一点。正如另一个接下来要提及的例子,就是 Kotlin 中的函数。与 Java 的函数不同,Kotlin 中所有的函数调用也都是表达式。

Kotlin核心编程(32):基础语法 2.4.1

购书地址 https://item.jd.com/12519581.html?dist=jd

评论

发布