Kotlin流程控制语句笔记

Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函数和扩展属性笔记 Kotlin空指针安全(null-safety)笔记 Kotlin类型系统笔记 Kotlin面向对象编程笔记 Kotlin委托(Delegation)笔记 Kotlin泛型型笔记 Kotlin函数式编程笔记 Kotlin与Java互操作笔记 Kotlin协程笔记

【Kotlin流程控制语句笔记】流程控制语句是编程语言的核心之一。跟java类似,Kotlin有以下的语句。
  • 分支语句 if、when
  • 循环语句 for、while
  • 跳转语句 return、break、continue、throw
1. if表达式
在Kotlin中,if是一个表达式,即它会返回一个值。if作为代码块时,最后一行作为返回值。
package com.dengyin2000.kotlintest1fun max(x: Int, y: Int): Int { return if (x > y) { println("max is $x") x }else{ println("max is $y") y } }fun main(vargs: Array){ val x = if (1 == 1) "abc" else "bcd" println(x)//打印abcprintln(max(1, 2)) //打印max is 2 //打印2 }

注意:Kotlin中没有java的中的2>1?2:1这样的三元表达式。
2. when表达式
Kotlin中的when表达式比java中的简单直接得多。如下:
when (x) { 1 -> print("x == 1") 2 -> print("x == 2") 3, 4 -> print("x == 3 or x == 4") in 5..9 -> print("x in [5..9]") is Long -> print("x is Long") !in 10..20 -> print("x is outside the range") parseInt(s) -> print("s encodes x") else -> { // Note the block print("x is funny") } }

像if一样,when的每个分支也可以是一个代码块,它的值就是代码块最后的表达式的值。甚至你可以像写if表达式一样写when:
when { x.isOdd() -> print("x is odd") x.isEven() -> print("x is even") else -> print("x is funny") }

前面的判断需要返回Boolean类型
3. for循环
Kotlin的for循环与java中的没有什么特别:
for (i in 1..4) { println(i) }val array = arrayOf(1, 2, 3, 4) for (i in array) { println(i) } for (i in array.indices) { println(array[i]) } for ((index, value) in array.withIndex()) { println("the element at $index is $value") }val map = hashMapOf("1" to 1, "2" to 2, "3" to 3) for (key in map.keys) { println(key) } for (value in map.values) { println(value) } for ((key, value) in map) { println("the key at $key is $value") }

4. while循环
while循环也没啥特别的。
5. break和continue
5.1 break 与java没啥区别,略过。
5.2 continue 与java没啥区别,略过。
6. return
在Kotlin中,除了表达式的值,有返回值的函数都要求显示使用return来返回值。
fun sum(x: Int, y: Int): Int { return x + y}fun max(a: Int, b: Int): Int {if (a > b) return a else return b}fun dive(a: Int, b: Int): Int = a / b

可以直接使用=符号直接返回一个函数的值。
Kotlin中return语句会从最近的函数或匿名函数中返回,但是在Lambda表达式中遇到return,则直接返回最近的外层函数。例如下面两个函数是不同的:
package com.dengyin2000.kotlintest1fun returnDemo1() { println(" start " + ::returnDemo1.name) val intArray = intArrayOf(1, 2, 3, 4, 5) intArray.forEach { if (it == 3) { return } println(it) } }fun returnDemo2() { println(" start " + ::returnDemo2.name) val intArray = intArrayOf(1, 2, 3, 4, 5) intArray.forEach ( fun(a: Int) { if (a == 3) { return } println(a) } ) }fun main(vargs: Array){ returnDemo1() returnDemo2() }

结果输出如下:
start returnDemo1 1 2 start returnDemo2 1 2 4 5

returnDemo1函数在遇到3时会直接跳出这个函数,因为是在Lambda表达式中,但是returnDemo2函数却只是忽略了3,因为只是跳出了匿名函数。
7. 标签(label)
在Kotlin中任何表达式都可以用标签来标记,标签的格式为标识符后跟@符号,例如:abc@、jump@。标签可以控制return、break和continue的跳转行为。
上面returnDemo1的例子,如果想修改成跟returnDemo2一样的结果的话,就可以用标签来实现。
fun returnDemo3() { println(" start " + ::returnDemo3.name) val intArray = intArrayOf(1, 2, 3, 4, 5) intArray.forEach here@{ if (it == 3) { return@here } println(it) } }

另外,我们也可以使用 隐式的标签更方便,该标签与接收该lambda的函数名相同。如下:
fun returnDemo4() { println(" start " + ::returnDemo4.name) val intArray = intArrayOf(1, 2, 3, 4, 5) intArray.forEach { if (it == 3) { return@forEach } println(it) } }

8. throw表达式
在Kotlin中throw是表达式,它的类型是特殊类型Nothing。该类型没有值。跟C、Java中的void的意思一样。
fun fail(msg: String): Nothing{ throw IllegalArgumentException(msg) }fun main(vargs: Array){ println(Nothing::class) //打印class java.lang.Void (Kotlin reflection is not available) val x = null//x的类型为Nothing? val l = listOf(null)//l的类型为List fail("oops") }

9. this、super关键字
9.1 this关键字 this关键字持有当前对象的引用。我们可以使用this来引用变量或者成员函数。在类的成员中,this指向的是该类的当前对象。
class Person{ val name = "Jake" val motherName = "Rose"fun sayMyName():Person{ println(this.name)//引用变量 println(this.sayMyFatherName())//引用成员函数 return this//返回当前Person实例 }fun sayMyFatherName() { println("Jack") } }fun main(vargs: Array){ val person = Person() val p = person.sayMyName() println(person === p) }

输出:
Jake
Jack
true
在扩展函数或者带接收者的函数字面值中,this表示在左侧传递的接收者参数。
fun Person.sayMyMotherName() = println(this.motherName)

如果this没有限定符,它指的是最内层的包含它的作用域。如果我们想要引用其他作用域中的this,可以使用this@label标签。
class Outer { val oh = "Oh!"inner class Inner {fun m() { val outer = this@Outer val inner = this@Inner val pthis = this println("outer=" + outer)//outer实例 println("inner=" + inner)//inner实例 println("pthis=" + pthis)//最近的外层作用域,inner实例 println(this@Outer.oh)val fun1 = hello@ fun String.() { val d1 = this // 扩展函数,这里的作用域是String println("d1" + d1) }val fun2 = { s: String -> val d2 = this//Lambda表达式的话,是最近的外层作用域,inner实例 println("d2=" + d2) }"abc".fun1()fun2("abc")} } }fun main(args: Array) { Outer().Inner().m() }

输出:
outer=com.dengyin2000.kotlintest1.Outer@2f0e140b inner=com.dengyin2000.kotlintest1.Outer$Inner@7440e464 pthis=com.dengyin2000.kotlintest1.Outer$Inner@7440e464 Oh! d1abc d2=com.dengyin2000.kotlintest1.Outer$Inner@7440e464

9.2 super关键字 super关键字可以持有指向父类的引用。
package com.dengyin2000.kotlintest1open class Father{ open val firstName = "Chen" open val lastName = "Jason"fun ff() { println("FFF") } }class Son : Father { override var firstName = super.firstName override var lastName = "Jack"constructor(lastName: String){ this.lastName = lastName }fun love() { super.ff() println("${super.firstName} ${super.lastName} Love ${this.firstName} ${this.lastName}") }}fun main(args: Array) { val son = Son("Jack") son.love() }

输出
FFF Chen Jason Love Chen Jack

    推荐阅读