玖叶教程网

前端编程开发入门

Kotlin官方文档翻译,基础:控制流、返回和转跳

以下内容皆有feint进行翻译,不定期进行更新。翻译若有不正确的地方,欢迎在评论中指出。

控制流

控制流: if, when, for, while

If 表达式

在Kotlin中If是一个表达式,也就是说它可以返回一个值。 所以在Kotlin中没有三元操作符 (condition ? then : else), 因为一般情况下If就能很好的扮演这一角色

// 传统用法

var max = a

if (a \< b) max = b

// 和else一起使用

var max: Int

if (a \> b) {

max = a

} else {

max = b

}

// 作为表达式

val max = if (a \> b) a else b

if的分支可以是语句块,并且将语句块的最后一个表达式做为该分支的返回值:

val max = if (a \> b) {

print("Choose a")

a

} else {

print("Choose b")

b

}

如果你把if当作一个表达式使用 (例如:直接返回它的值,或把它赋给另一个变量), 那么该表达式必须要有一个 else 分支.

参照 if 的语法中的if。

When 表达式

when用来替换类C语言中的switch。 它最简单的形式就像这样子:

when (x) {

1 -> print("x == 1")

2 -> print("x == 2")

else -> { // Note the block

print("x is neither 1 nor 2")

}

}

when 依次比较参数和各分支的条件,直到匹配的时候,该分支才能被执行。 when 既可以作为表达式也可以作为语句进行使用。 如果当作一个表达式使用, 匹配分支的值作为整个表达式的值。 如果作为一个表达式使用,每个独立分支的值会被忽略。 (就像If一样,每个分支都可以是一个语句块,该语句块的值是当中最后一个表达式的值。)

else分支在其他分支都不匹配的情况下将被执行。 如果when 作为一个表达式, else分支是强制要求的, 除非编译器能证明分支条件覆盖了所有的可能性.

如果有几种情况对应着同一种处理方法,通过逗号将分支条件组合到一起:

when (x) {

0, 1 -> print("x == 0 or x == 1")

else -> print("otherwise")

}

我们可以使用任意表达式(不仅仅是常数)作为分支条件:

when (x) {

parseInt(s) -> 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

}

when 也可以用来替代 if-else 链。如果没有参数的话, 分支条件是简单的布尔表达式, 并且分支只有在条件为真的时候执行:

when {

x.isOdd() -> print("x is odd")

x.isEven() -> print("x is even")

else -> print("x is funny")

}

参照 when 的语法.

For 循环

for循环用来遍历任何提供了迭代器的东西. 这等价于在类C#语言中的 foreach 循环 。 其语法是这样子的:

for (item in collection) print(item)

循环体可以是一个语句块:

for (item: Int in ints) {

// ...

}

正如之前所提到的,for循环可以遍历任何提供了迭代器的东西,也就是说:

  • 有一个成员或扩展函数 iterator(), 其返回值:

  • 有一个成员或扩展函数 next(), 并且

  • 有一个成员或扩展函数 hasNext() 返回 Boolean.

这三个函数全都需要用 operator 关键字进行标记.

一个数组的 for 被编译成基于下标的循环,而不需要创建一个迭代器对象。

如果你想通过下标遍历一个数组或是列表,你可以这么做:

for (i in array.indices) {

print(array[i])

}

注意: "遍历一个范围" 在编译的时候进行了优化,而不需要创建额外的对象。

还有一种方法, 你可以使用库函数 withIndex :

for ((index, value) in array.withIndex()) {

println("the element at $index is $value")

}

参照 for 的语法.

While 循环

while 和 do..while

while (x \> 0) {

x--

}

do {

val y = retrieveData()

} while (y != null) // y is visible here!

参照 while 的语法.

循环中的 Break and continue

Kotlin 支持循环中传统的 break and continue 操作. 见 返回和转跳.

返回和转跳

Kotlin中有三种结构的转跳表达式:

  • return。 默认从最近的函数或 匿名函数返回。

  • break。 结束最近的循环。

  • continue。 继续最近一个循环的下一步.

这些表达式全都可以作为更大的表达式的一部分:

val s = person.name ?: return

这些表达式的类型是 没有类型.

Break and Continue 标签

Kotlin中任何表达式都可以使用标签进行标记。 标签的格式是标识符后面跟着 @ 符号。 例如: abc@, fooBar@ 都是合法的标签 (参照 语法)。 为表达式添加标签时,需要将标签放在表达式的前面。

loop@ for (i in 1..100) {

// ...

}

现在,我们可以把 break 或是 continue 和一个标签一起使用:

loop@ for (i in 1..100) {

for (j in 1..100) {

if (...) break@loop

}

}

被标签限制的 break 转跳出被这个标签标记的循环。continue 继续那个循环的下一次遍历。

带标签的返回

在 Kotlin 中,有函数字面量、本地函数、和对象表达式,因此函数是可以嵌套的。 我们可以合法的从外部的函数进行返回. 其中最值得在意的是,从lambda表达式中返。回想起我们写的这段代码:

fun foo() {

ints.forEach {

if (it == 0) return// nonlocal return from inside lambda directly to the caller of foo()

print(it)

}

}

return 表达式从最近的一个函数返回, 也就是 foo 函数。 (注意: 这种非局部返回仅仅支持从lambda表达式传递到 内联函数。) 如果我们需要从一个lambda表示返回, 我们需要对return使用标签进行限制:

fun foo() {

ints.forEach lit@ {

if (it == 0) return@lit

print(it)

}

}

现在,我们只是从一个lambda表达式中返回量。 大部分时候为了方便,我们可以使用隐式标签:标签可以使用接受lambda表示的函数的名字。

fun foo() {

ints.forEach {

if (it == 0) return@forEach

print(it)

}

}

还有一种方法, 我们可以使 匿名函数替代lambda表达式。匿名函数中的return语句会从这个匿名函数中返回。

fun foo() {

ints.forEach(fun(value: Int) {

if (value == 0) return// 局部返回至匿名函数的调用者,也就是 forEach 循环

print(value)

})

}

当返回一个值时, 被标签限制的return具有优先权, 也就是:

return@a 1

意味着: "在标签 @a 处返回 1 " 而不是 "返回一个标签表达式 (@a 1)".

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言