1、If 表达式
if
是一个表达式,它会返回一个值;相当于其他语言中的三元运算符(条件 ? 然后 : 否则
)
//最后的表达式作为该块的值
val max = if (a > b) {
print("Choose a")
a // 最后一行做为返回值
} else {
print("Choose b")
b // 最后一行做为返回值
}
2、When 表达式
when 既可以作为表达式使用,也可以作为语句使用
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when (x) {
0, 1 -> print("x == 0 or x == 1") // 多个条件使用“,”组合在一起
else -> print("otherwise")
}
when (x) {
s.toInt() -> print("s encodes x") // 可以用任意表达式(而不只是常量)作为分支条件
else -> print("s does not encode x")
}
// 可以检测一个值在(in)或者不在(!in)一个区间或者集合中
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
// 可以检测一个值是(is)或者不是(!is)一个特定类型的值
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
// 可以用来取代 if-else if 链,不提供参数时,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支
when {
x.isOdd() -> print("x is odd")
y.isEven() -> print("y is even")
else -> print("x+y is odd")
}
// 可以when 所判断的表达式捕获到变量中
// 变量的作用域仅限于 when 主体
fun Request.getBody() =
when (val response = executeRequest()) {
is Success -> response.body
is HttpError -> throw HttpException(response.status)
}
当做表达式时(必须有 else
分支,除非编译器能够检测出所有的可能情况都已经覆盖了), 第一个符合条件的分支的值就是整个表达式的值;当做语句时, 则忽略个别分支的值;类似于 if
,每一个分支可以是一个代码块,它的值是块中最后的表达式的值
enum class Bit {
ZERO, ONE
}
val numericValue = when (getRandomBit()) {
Bit.ZERO -> 0
Bit.ONE -> 1
// 'else' 可不需要这个分支,因为只能是枚举类型的两个值
}
when (getRandomBit()) {
Bit.ZERO -> println("ZERO") // 缺少 ONE
else -> println("Not ZERO") // 'else' 所以必须 else
}
3、For 循环
for
可以循环遍历任何提供了迭代器的对象
// 对任何提供迭代器(iterator)的对象进行遍历
for (item in collection) print(item)
// 循环体可以是一个代码块
for (item: Int in ints) {
// ……
}
// 在数字区间上迭代
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
// 遍历一个数组或者一个 list
val array = arrayOf("a", "b", "c")
// 通过索引
for (i in array.indices) {
println(array[i])
}
// 使用库函数 withIndex
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
4、while 循环
while do-while
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此处可见
5、返回与跳转
三种结构化表达式
return
默认从最直接包围它的函数或者匿名函数返回(最重要的一个用途就是从 lambda 表达式中返回)break
终止最直接包围它的循环continue
继续下一次最直接包围它的循环
这里请引起注意是 表达式 表达式 表达式,所有这些表达式都可以用作更大表达式的一部分,类型是 Nothing 类型
val s = person.name ?: return
一个跳转辅助标签
- 标签 标记任何表达式 (标签的格式:标识符后跟
@
符号)
// 添加loop1标签
loop1@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop1 // 使用标签,跳转到该标签指定的循环后面的执行点
}
}
// 添加loop2标签
loop2@ for (i in 1..100) {
for (j in 1..100) {
if (……) continue@loop2 // 使用标签,继续标签指定的循环的下一次迭代
}
}
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者——forEach 循环
print(it)
}
// 隐式标签
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者——forEach 循环
print(it)
}
// 匿名函数替代 lambda 表达式
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // 局部返回到匿名函数的调用者——forEach 循环
print(value)
})
return@a 1 // 意味着“返回 1 到 @a”,而不是“返回一个标签标注的表达式 (@a 1)”