文章结构:
- 分支语句(if、when)
- 循环语句(for、while)
- 跳转语句(break、continue、return、label、throw)
分支语句(if、when)
if 表达式
- 在kotlin中 if是一个表达式,它会返回一个值
- if分支可以是代码块,最后的表达式作为该块的值(最后一行为其返回值)
fun main(args: Array<String>) {
println("hello kotlin !")
println(max(2,9))
println(max2(2,9))
println("facts(2) = ${facts(2)}")
println("facts(10) = ${facts(10)}")
}
fun max(x: Int, y: Int): Int {
return if (x > y) x else y
}
fun max2(x: Int, y: Int): Int {
val max = if (x>y) {
println("max is x")
x // 最后的表达式作为该块的值
} else {
println("max is y")
y // 最后的表达式作为该块的值
}
return max
}
/**
* 阶乘函数
*/
fun facts(n: Int): Int {
return if (n <= 1) 1 else n * facts(n - 1)
}
- 在kotlin中没有类似Java的三元表达式
true?1:0 ,对应的写法是if...else 语句
if后的括号不能省略,括号中的表达式值必须是布尔型。
?
when 表达式
when ?表达式类似于?switch...case 表达式;
when ?会对所有分支进行检查,直到有一个条件满足
fun main(args: Array<String>) {
whenFx(3)
whenFx('U')
whenFx("hello")
whenFx("world")
whenFy(3)
whenFy(10)
whenFy(23)
whenFy(30)
whenFy(60)
whenFy(-1)
println("${fact(2)}")
println("${fact(10)}")
}
fun whenFx(x: Any?): Unit {
when(x) {
// 如果很多分支需要相同的处理方式,那么可以把多个分支条件放在一起,用逗号分隔:
0,1,2,3,4,5 -> println("$x 是一个 0~5 之间的整数")
is Char -> println("$x 是一个 Char类型的数据")
"hello" -> println("$x 是一个 字符串hello")
else -> println("[$x] else 类似于 java switch...case 中的 default.")
}
}
/**
* 检测一个值是否在某个区间/集合中
*/
fun whenFy(x: Int): Unit {
val validNum = arrayOf(1,2,3)
when(x) {
in validNum -> println("$x 在集合(1,2,3)中")
in 1..10 -> println("$x 在范围 1..10 中")
!in 10..30 -> println("$x 不在范围 10..30 中")
else -> println("$x , default..")
}
}
/**
* 阶乘函数
*/
fun fact(n: Int): Int {
var data = -1;
data = when(n) {
0,1 -> 1
else -> n* fact(n-1)
}
return data;
}
?
循环语句(for、while)
for循环
for循环可以对任何提供迭代器的对象进行遍历。
iterator
fun main(args: Array<String>) {
forInArray()
forInRange()
}
fun forInArray(): Unit {
val arr = arrayOf(1,2,4,8,16)
// for in 循环
for (x in arr) {
println(x)
}
for (i in arr.indices) {
// arr.indices 持有数组的下标列表
println("$i , ${arr[i]}")
}
for ( (index,value) in arr.withIndex() ) {
// arr.withIndex() 函数持有数组的(下标,值)列表
println("$index : $value")
}
}
/**
* 范围表达式中使用 for循环
*/
fun forInRange(): Unit {
for (i in 10..20) {
println(i)
}
// 等价于
(10..20).forEach { x ->
println("item: $x")
}
}
while循环
while ?和?do...while 循环语句的使用方法与C、Java语言基本一致。
fun main(args: Array<String>) {
println("while: ")
whileF()
println("\ndo...while: ")
doWhileF()
}
fun whileF(): Unit {
var x = 10
while (x>5) {
x--
print("$x ")
}
}
fun doWhileF(): Unit {
var y = 10
do {
y++
print("$y ")
} while (y<1)
}
跳转语句(break、continue、label、return、throw)
break、continue
break 、continue ?语句都是用来控制循环结构的,用来停止循环/中断跳转。
break ?语句用于完全结束一个循环,直接跳出循环体;continue ?语句用于终止本轮循环,但还是会继续下一轮循环;
?
return 语句
- 有返回值的函数都要求显式使用
return ?语句返回其值。 - 函数字面量:kotlin中可以直接使用“
=” 符号返回一个函数的值,这样的函数称为‘函数字面量’。
fun main(args: Array<String>) {
val r= sum(1,3)
println(r)
println(sumF(5,5)) // 输出:() -> kotlin.Int,sumF(5,5)的返回值是一个函数,即 () -> kotlin.Int
println(sumF(5,5).invoke()) // 输出:10,invoke()函数实现sumF函数的调用
println(sumF(5,5)()) // 输出:10,()运算符的作用等价于invoke()函数
println(sumF2(5,15)) // 输出:() -> kotlin.Int,
println(sumF2(5,15).invoke()) // 输出:20
println(sumF2(5,15)()) // 输出:20
}
// 使用表达式声明sum()函数
fun sum(x: Int, y: Int) = x+y
// 使用fun关键字声明了一个匿名函数,同时直接使用表达式来实现函数
// { x+y } 的类型是 () -> kotlin.Int 函数;{ x+y }表达式返回的是一个Lambda表达式
// ?? x+y 与 { x+y } 的区别
val sumF = fun(x: Int, y: Int) = { x+y }
// 使用表达式声明 sumF2()函数,{}表示一个Lambda表达式
// ?? x+y 与 { x+y } 的区别
fun sumF2(x: Int, y: Int) = { x + y };
- kotlin中的return语句 与 lambda表达式中的return语句的区别
- kotlin中的return语句会从最近的函数(或匿名函数)中返回 (类似循环体中continue语句效果)
- lambda表达式中的return语句 直接返回到最近的外层函数 (类似循环体中break语句效果)
fun returnInKotlinVsLambda(): Unit {
val arr = intArrayOf(1,2,3,4,5) // 声明一个Int数组
println("return in kotlin function:")
arr.forEach (
fun(x: Int) { // 给forEach传入一个函数,该函数中的return语句不会跳出forEach
if (x == 3) return // 类似循环体中continue语句效果
println(x) // 输出:1,2,4,5
}
)
println("return in kotlin lambda:")
arr.forEach {
// 在lambda表达式中的return语句 直接返回到最近的外层函数
if (it == 3) return //类似循环体中break语句效果
println(it) // 输出:1,2
}
}
?
Label标签
使用Label标签来控制 return、break、continue语句的跳转行为。 任何表达式都可以使用Label标签来标记。
fun labelF(): Unit {
val arr = intArrayOf(1,2,3,4,5) // 声明一个Int数组
println("显式标签:")
arr.forEach jump@ { // jump@ 是一个标签
if (it == 3) return@jump // 执行跳转到lambda表达式标签 jump@ 处,继续forEach循环
println(it) // 输出:1,2,4,5
}
println("隐式标签:")
arr.forEach { // 隐式标签 与接收该lambda的函数同名
if (it == 3) return@forEach // 返回@forEach 处,继续下一个循环
println(it) // 输出:1,2,4,5
}
}
?
throw
kotlin中throw 是表达式,它的类型是特殊类型?Nothing 。
Nothing 类型没有值,与C、Java中的void一样。
fun main(args: Array<String>) {
// 使用 :: 类引用操作符,返回Nothing的类型
// 输出:class java.lang.Void
println("${Nothing::class}")
fail("param type is error !")
}
fun fail(x: String): Nothing {
throw IllegalArgumentException(x)
}
?
知识点参考:《Kotlin从入门到进阶实战》陈光剑?
|