前置知识
- 已学习 Kotlin 变量、函数知识
- 有
Java
编程基础
前言
本系列的上一篇文章中,笔者给大家讲述 kotlin
中的 头等公民 ——函数,相信 Kotlin
中函数的简单使用大家都很熟悉了,现在继续给大家讲述 Kotlin
中的逻辑控制语句。
本篇主要讲述三大执行语句中的 条件判断语句 和 循环语句,由于顺序执行语句与 Java
一样,没什么特点,我们前面文章中也多次使用过了,这里便不再赘述。
条件判断语句
if 语句
Kotlin
中 if
语句的实现和 java 中的 if
是没有太大区别的。我们需要关注的是其特性和表达式化这些与 Java 不同的地方。
首先,我们依旧是用一段简单的 Java 代码来进行变化。
public int numMax(int num1, int num2){ int res = 0; if(num1 > num2){ res = num1; }else{ res = num2; } return res; } 复制代码
转化为 Kotlin 之后,是如下方的代码。这一段转换,使用到的是我们前文中使用到的一些内容,直接把函数给转化。
fun numMax(num1: Int, num2: Int): Int{ var res = 0 if(num1 > num2){ res = num1 }else{ res = num2 } return res } 复制代码
但是上面这段代码的转化,显然是少一些 Kotlin 的特点的。什么特点呢?首先是 if 函数自身的特点。if 函数可以 表达式化/函数化 ,在这种情况下,可以直接把每个条件下的最后一条语句作为返回值。这是什么意思呢?具体看下面的代码变化。
fun numMax(num1: Int, num2: Int): Int{ var res = if(num1 > num2){ num1 }else{ num2 } return res } 复制代码
由上面的代码我们可以看到,当其 res 的赋值是表达式的时候,表达式中最后一行不能出现 res = xxx
这种类型的语句,因为 if 语句变为表达式的时候,是需要把最后一行作为结果返回的,所以最后一行需要是一个结果。
我们再次把它变化得更具 Kotlin
风格,这次是将 if 表达式直接作返回值返回。
fun numMax(num1: Int, num2: Int): Int{ return = if(num1 > num2){ num1 }else{ num2 } } 复制代码
同样的,既然函数体里面只返回一个 if 表达式,那么我们可以直接把 if 表达式继续向外提出,让整个函数体变为一个 if 表达式的结果。变化后的代码如下。
fun numMax(num1: Int, num2: Int) = if(num1 > num2) num1 else num2 复制代码
是的,这段代码最后变成了一行代码了,变成了纯表达式化的代码。这里要注意的是,把整个函数变成 if 表达式之后,对应的函数的声明也去掉了,这正对应我们上一篇文章所讲的知识点。
when 语句
Kotlin
中的 when
语句,大家初次听也许感觉很陌生。但是事实上,你可以将其看作是 Java
中 switch
语句的加强版本。在 Kotlin
中,已不再有 switch
语句,全面使用 when
语句替代。when
语句即保留了 swich
语句的多重判定,同时又让其使用变得无比简洁且可接收各种类型的参数。所以,你也可以把 when
理解为多重 if 的简化版。
我们依旧以 Java 版本,先写出一段多重 if
语句代码。这里为什么不以 switch
举例?是因为 switch
语句直到在 jdk 1.7 以下只支持 int
类型变量,所以此处不以其作为例子。
下面的这段代码很简单,就是对传入的字符串作判断,根据不同的字符串来返回不同的整形数值。
public int checkString(String s){ int sNum = 0; if(s.equals("a")){ sNum = 1; }else if(s.equals("b")){ sNum = 2; }else if(s.equals("c")){ sNum = 3; } return sNum; } 复制代码
将上述的代码转化为 Kotlin
,使用 when
语句来编写,就是如下的样式:
fun checkString(s: String) = when(s){ "a" -> 1 "b" -> 2 "c" -> 3 else -> 0 } 复制代码
是否顿时觉得变得无比明了简单呢!你会发现这种形式更加的适合人的思维。相比于 switch
和多重 if,这也让我们的代码编写过程变得更加简单。
从上面的示例代码,我们可以看出三点。
when()
语句可以传入参数,事实上这个参数可以是任意类型的;when
下边的代码编写格式为:"匹配条件" -> {}
,这里没有了{}包含的函数体,是因为它是单行的,所以将其视为表达式,把 {} 省略了;- 当
when
语句需要返回值的时候,是以每个条件下的最后一行表达式作为返回值。
但是 when
的功能远不止于此,让我们来看一下下面的代码。
fun checkInt(i: Any) = when(i){ in 1..20 -> 1 //1 is Long,Double -> 2 //2 13 -> 3 //3 else -> 0 } 复制代码
可以看到,上文中的每行的表达式和前面代码不一样了,其实这正体现了 when
广阔的判断功能。
上述的 注释1 处,判断 i 是否在 [1,20] 的区间内,其中 in 和 1..20 这两种用法,我在接下来的循环语句中会讲述含义和用法;
注释2 处,判断 i 是否为 Long
或者 Double
类型的,is 我们可以理解为 Java
中的 instanceof
,用于查看是否为对应子类的;
注释3 处,便是和前面一样,判断是否为13了。
同时,当带有参数的功能不再满足于现有要求的时候,我们还可使用无参的 when
语句
fun checkString(s: String) = when{ s.length == 2 -> 1 s.startsWith("a") -> 2 s == "c" -> 3 else -> 0 } 复制代码
上述这段无参的 when
语句块,让我们的代码变得更加灵活,使得可以对各种外部的属性作判断,也可以对属性作各种 Boolean
类型的逻辑判断。所以说,when
更像是多重 if 的简约版本,功能强大的同时,使用也便捷。
循环语句
Kotlin 中的循环语句,包括 while
和 for
这两种循环语句。其中,while
语句和 Java
中的一样,倒是 for
语句在 Kotlin
中有很多不同,所以只在此介绍 for
语句。
for 语句
Kotlin 中的 for 语句,完全摒弃了传统的 for-i
循环,全面使用 for-each
循环。但是同时也对 for-each
循环做了一个拓展,让其变得简单易用。
在 Kotlin 中,我们可以将改进后的 for-each
循环称之为 for-in
循环。老规矩,我们先上一段 Java 代码,再对其进行转化。
private final List<ShoppingCartItem> items = new ArrayList<>(); public List<ShoppingCartItem> getItems() { List<ShoppingCartItem> copyItems = new ArrayList<>();; for (ShoppingCartItem i : items){//1 copyItems.add(i.clone()); } return Collections.unmodifiableList(copyItems); } 复制代码
上面这段代码来自于我的 设计模式系列 中。可以看到上述的代码的注释1处使用了 for-each
。我们将其转化为 Kotlin
之后是这样子的。
private val items: MutableList<ShoppingCartItem> = ArrayList() fun getItems(): List<ShoppingCartItem> { val copyItems: MutableList<ShoppingCartItem> = ArrayList() for (i in items) {//1 copyItems.add(i.clone()) } return Collections.unmodifiableList(copyItems) } 复制代码
可以看到,最不一样的地方,就是 for-each
中的 :变成 in
了。这里是遍历集合,我们很好理解。
但是,要实现 Java 的 for-i
的用法该怎么办呢?在 Kotlin
中也有对应拓展的。
在介绍之前,我们先学习几个知识。
0..10 //代表的是 [0,10],左闭右闭 0 until 10 //代表的是 [0,10),左开右闭 复制代码
由此,我们可以写出 for-i
中1遍历到10的代码为:
for (i in 0..10) { // Loop over a range from 0 to 10 print(i) } 复制代码
使用 until
关键字, for-i
中1遍历到10的代码可以写成:
for (i in 0 until 11) { // Loop over a range from 0 to 10 print(i) } 复制代码
Kotlin 中的 for-in
默认是正序且步长为1的,我们可以分别使用 downTo
和 step
两个关键字对其作更改 。
for (i in 10 downTo 1 step 2) { print(i) } 复制代码
上述代码的运行结果为: