Kotlin语法基础(二)----流程控制

94 阅读2分钟

一、when

1.1 when语句

相较于我们比较熟悉的Switch关键字,Kotlin的When关键字提供了一种更加灵活和简洁的结构,结合Lambda表达式用来进行条件的判断.

fun main() {

    cases("Hello")
    cases(1)
    cases(0L)
    cases(MyClass())
    cases("hello")

}

fun cases(obj: Any) {
    when (obj) {
        1 -> println("One")
        "Hello" -> println("Greeting")
        is Long -> println("Long")
        !is String -> println("Not a String")
        else -> println("Unknown")
    }
}
Greeting
One
Long
Not a String
Unknown

可以看到,在上面的when语句中对obj进行了分支的判断,由于入参的类型是Any,所以接受了各种类型的参数,可以是详细的某个数值的判断,也可以是简单的参数类型判断,也支持else操作符.

1.2 when表达式

class MyClass

fun main() {

    println(whenAssign("Hello"))
    println(whenAssign(3.4))
    println(whenAssign(1))
    println(whenAssign(MyClass()))

}

fun whenAssign(obj: Any): Any {
    val result = when (obj) {
        1 -> "One"
        "Hello" -> 1
        is Long -> false
        else -> 42
    }
    return result
}

上面的whenAssign方法接受的入参和返参都是Any类型,使用when语句表达式对接收的obj入参进行相应判断并且反正不同类型的条件语句.可以看到,这里面的条件判断语句是默认返回42的。

image.png

在when语句中,是需要else表达式做所有条件的判断的.

二、Loop循环

Kotlin支持的循环模式有如下几种:for,while,do-while

2.1 for循环

fun main() {
    val cakes = listOf("carrot", "cheese", "chocolate")

    for (cake in cakes) {
        println("Yummy,it's a $cake cake !")
    }
}
Yummy,it's a carrot cake !
Yummy,it's a cheese cake !
Yummy,it's a chocolate cake !

写法与java的for循环很相似,迭代器遍历每个参数.

2.2 while和do-while

fun eatACake() = println("Eat a Cake")
fun bakeACake() = println("Bake a Cake")

fun main() {

    var cakesEaten = 0
    var cakesBaked = 0

    while (cakesEaten < 5) {
        eatACake()
        cakesEaten++
    }

    do {
        bakeACake()
        cakesBaked++
    } while (cakesBaked < cakesEaten)
}

while语句和do-while语句和我们之前所熟悉的循环逻辑也是一致的.while语句是需要语句块判断条件为true的时候执行,do-while是先执行语句块再判断条件.

2.3 Iterators迭代器

class Animal(val name: String)

class Zoo(private val animals: List<Animal>) {
    operator fun iterator(): Iterator<Animal> {
        return animals.iterator()
    }
}

fun main() {
    val zoo = Zoo(listOf(Animal("zebra"), Animal("lion")))

    for (animal in zoo) {
        println("Watch out,it's a ${animal.name}")
    }
}

使用list的默认迭代器 对动物的名字进行输出.

Watch out,it's a zebra
Watch out,it's a lion
class Zoo(private val animals: List<Animal>) {
    operator fun iterator(): Iterator<Animal> {
        return object : Iterator<Animal> {
            override fun next(): Animal {
                return Animal("111")
            }

            override fun hasNext(): Boolean {
                return true
            }
        }
    }
}

fun main() {
    val zoo = Zoo(listOf(Animal("zebra"), Animal("lion")))

    for (animal in zoo) {
        println("Watch out,it's a ${animal.name}")
    }
}

我们也可以自己去实现迭代器进行集合的迭代逻辑.

三、Ranges区间

kotlin还提供了一系列工具用于区间的数据处理,kotlin的Ranges区间和Python中的步长很相似

for (i in 0..3) {
    print(i)
}

print(" ")

for (i in 2..8 step 2) {
    print(i)
}
print(" ")

for (i in 3 downTo 0) {
    print(i)
}
print(" ")
  • 第一个for循环从0循环遍历到3,输出0 1 2 3
  • 第二个for循环从2循环遍历到8,输出2 4 6 8
  • 第三个for循环从3到0倒序遍历,输出3 2 1 0

char数组也支持同样的操作.

for (c in 'a'..'d') {
    print(c)
}

print(" ")

for (c in 'z' downTo 's' step 2) {
    print(c)
}
print(" ")
abcd zxvt 

in 关键字同样支持用在if语句中

val x = 2
if (x in 1..5) {
    print("$x is in range from 1 to 5")
}
println()

if (x !in 6..10) {
    print("x is not in range from 6 to 10")
}
2 is in range from 1 to 5
x is not in range from 6 to 10

四、相等关系检查

在kotlin中,使用==来比较结构是否相等.使用 === 来比较引用地址是否相等.

a==b 编译完之后等价于 if(a==null) b==null else a.equals(b)

val authors = setOf("Shakespeare", "Hemingway", "Twain")
val writers = setOf("Twain", "Shakespeare", "Hemingway")
val writes1 = setOf("Twain", "Shakespeare", "Hemingway")
val writes2 = writers

println(authors == writers)
println(authors === writers)
println(writers === writes1)
println(writes2 === writers)
true
false
false
true
  • 第一个表达式返回true是因为调用了authors.equals(writes),sets几乎会忽略集合中元素的顺序
  • 第二个表达式返回false是因为authors和writes不是同样的引用地址
  • 第三个表达式返回false是因为虽然writes和writes1集合元素相等,但是两者指向得并不是相同的引用地址.
  • 第四个表达式返回true是因为指向了同一个对象

五、多元表达式Conditional Expression

在kotlin中没有java的 a?b :c的三元表达式,相反,我们可以使用这种表达.

fun main() {
    println(max(99, -42))
}

fun max(a: Int, b: Int) = if (a > b) a else b