Kotlin中的流程控制语句

本文详细介绍了Kotlin中的流程控制语句,包括if-else的传统与表达式用法,强大的when语句,for和while循环,以及返回与跳转操作如break、continue和return。特别地,文章讨论了标签在控制流程中的应用,如如何配合break和continue改变循环行为。
摘要由CSDN通过智能技术生成

流程控制语句是编程语言中的核心之一。可以分为 分支语句、循环语句和跳转语句。下面我们深入的了解Kotlin的流程控制语句。

if

if-else语句是控制程序流程的最基本的形式,其中else是可选的。

在Kotlin中,if是表达式,比如它可以返回一个值。 是除了condition ? then : else)之外的唯一一个三元表达。

传统用法

val a = 10
val b = 20
var max_0: Int = a

if (a > b) {
    max_0 = a

} else {
    max_0 = b
}

println("----------------------------------")
println("max_0:$max_0")
println("----------------------------------")

// Log
--------------
max_0:20
--------------

作为表达式

var max_1 = if (a > b) a else b
println("--------------")
println("max_1:$max_1")
println("--------------")

//Log
--------------
max_1:20
--------------

作为代码块

println("--------------")
val max_2 = if (a > b) {
    println("Choose a")
    a
} else {
    println("Choose b")
    b
}

println("max_2:$max_2")
println("--------------")

// Log	
--------------
Choose b
max_2:20
--------------

if作为代码块时,最后一行必须为该块的返回值.

如果 if 表达式只有一个分支, 或者分支的结果是 Unit , 它的值就是 Unit 。

if-else语句规则:

  • if后的括号不能省略,括号里表达式的值最终必须返回的是布尔值
  • 如果条件体内只有一条语句需要执行,那么if后面的大括号可以省略,但这是一种极为不好的编程习惯。
  • 对于给定的if,else语句是可选的,else if 语句也是可选的
  • else和else if同时出现时,else必须出现在else if 之后
  • 如果有多条else if语句同时出现,那么如果有一条else if语句的表达式测试成功,那么会忽略掉其他所有else if和else分支。
  • 如果出现多个if,只有一个else的情形,else子句归属于最内层的if语句

when

when取代了C风格语言的switch。相较switch而言,when语句显得更加的强大,灵活性更好。

when会对所有的分支进行检查直到有一个条件满足。 when 可以用做表达式或声明。如果用作表达式的话,那么满足条件的分支就是总表达式。如果用做声明,不满足条件的分支的的的值会被忽略,只保留满足条件的分支,而且返回的值也是最后一个表达式的值。

传统用法

val x : Int = 10

when (x) {
    9 -> println("x:${x + 10}")
    10 -> println("x:$x")
    else -> print("x:$x")
}

分支条件一致

如果有分支可以用同样的方式处理的话, 分支条件可以连在一起处理。

when (x) {
	0,1 -> print("x == 0 or x == 1")
	else -> print("otherwise")
}

使用任意表达式作为分支的条件

when (x) {
	parseInt(s) -> print("s encode x")
	else -> print("s does not encode x")
}

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")
}

作为表达式

val hasPrefix = when (x) {
	is String -> x.startsWith("prefix")
	else -> false
}

for

for 循环通过任何提供的迭代器进行迭代。 语法如下:

for (item in collection)
	print(item)

如果遍历list或者array可以通过索引进行迭代:

for (i in array.indices)
	print(array[i])

while循环

while语句

while语句在循环刚开始时,会计算一次布尔表达式的值,如果满足条件,进入循环,如果不满足条件,将跳出循环。而在while语句的下一次迭代开始前会计算再一次布尔值,如此重复。

while (x > 0) {
	x--
} 

#dowhile语句
dowhile语句与while语句类是,唯一的区别是doWhile语句会至少执行一次,即便布尔表达式的第一次计算就是false.而while语句中,如果 布尔表达式的第一次计算的值是false,该循环不会执行。

do {
	val y = retrieveData()
} while (y != null) // y 在这是可见的

返回与跳转

Kotlin中有return、break、continue等三种返回跳转操作符。

  • return

    1. 指定一个方法返回什么值

    2. 导致当前方法结束,并返回返回指定的值

       fun main(args: Array<String>) {
       
       
           println("testA:${testA(10)}")
       
           println("----------")
       
           println("testB:${testB(10)}")
       }
      
       fun testA(a : Int):Int{
           if (a > 0) {
               return -1
           } else {
               return 1
           }
       }
       
       fun testB(a : Int):Int{
       
           println("a:$a")
       
           if (a > 0) {
               return -1
           } else {
               return 1
           }
       
           a++
       
           print("a:$a")
       }
      
       // Log打印
       testA:-1
       ----------
       a:10
       testB:-1
      
  • break
    结束最近的闭合循环,不执行循环中剩余的语句

      val arraysA = listOf("A", "B", "C", "D")
      val arraysB  = listOf(1,2,3,4)
      for (itemA in arraysA) {
      	for (itemB in arraysB) {
      		if (itemB > 2) {
      			break
      		}
      		println("itemB:$itemB")
      	}
      
      	if (itemA == "C") {
      		break
      	}
      	println("itemA:$itemA")
      }
      
      // Log
      itemB:1
      itemB:2
      itemA:A
      itemB:1
      itemB:2
      itemA:B
      itemB:1
      itemB:2
    

从Log打印可以看出,第一个break结束的是for (itemB in arraysB)这个循环,而第二个break结束的是for (itemA in arraysA),它们的共通点就是结束都是距离它们最近的一个循环。

  • continue
    跳到最近的闭合循环的下一次循环

      val arraysA = listOf("A", "B", "C", "D")
      val arraysB  = listOf(1,2,3,4)
      
      for (itemA in arraysA) {
      	var i : Int = 0
      	for (itemB in arraysB) {
      		i++
      		if (itemB > 2) {
      			continue
      		}
      
      		println("itemB:$itemB")
      	}
      
      	if (itemA == "C") {
      		continue
      	}
      	println("i:$i")
      	println("itemA:$itemA")
      	println("---------")
      }
      
      // Log
      itemB:1
      itemB:2
      i:4
      itemA:A
      ---------
      itemB:1
      itemB:2
      i:4
      itemA:B
      ---------
      itemB:1
      itemB:2
      itemB:1
      itemB:2
      i:4
      itemA:D
      ---------	
    

从上述Log上,可以清楚看到,两个循环分别循环了四次,但是在碰到continue时,会跳出当前循环并执行下一次循环。
#标签
在 Kotlin 中表达式可以添加标签,标签通过@结尾来表示,比如:abc@,fooBar@

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

break和标签

loop@ for (itemA in arraysA) {
    var i : Int = 0
    for (itemB in arraysB) {
        i++
        if (itemB > 2) {
            break@loop
        }

        println("itemB:$itemB")
    }

    println("i:$i")
    println("itemA:$itemA")
    println("---------")
}

// Log打印
itemB:1
itemB:2

从Log打印,第一个循环执行了一次,第二个循环执行了两次,便跳出了封闭的循环。意味着break跳到标签后边的表达式,并不再执行此表达式直接跳过,执行后边的语句。

continue和标签

loop@ for (itemA in arraysA) {
    var i : Int = 0
    for (itemB in arraysB) {
        i++
        if (itemB > 2) {
            continue@loop
        }

        println("itemB:$itemB")
    }

    println("i:$i")
    println("itemA:$itemA")
    println("---------")
}

// Log打印
itemB:1
itemB:2
itemB:1
itemB:2
itemB:1
itemB:2
itemB:1
itemB:2

之前说过,continue是跳到最近的闭合循环的下一次循环,但是加上标签以后,直接跳转到了第一个循环,也就是for (itemA in arraysA),并没有执行最近的闭合循环的下一次循环。意味着continue直接跳转到标签后面的语句并执行。

return和标签

val ints = listOf(0, 1, 2, 3)

fun main(args: Array<String>) {

    foo()

}

fun foo() {
    ints.forEach {
        if (it ==0) return@forEach
        println(it)
    }
}

// Log打印
1
2
3

fun foo() {
	ints.forEach {
	if (it ==0) return@forEach
		print(it)
	}
}

从Log打印可以看出,return会跳转到标签后边的表达式处,并执行该表达式。

命名函数自动定义标签

fun outer(){

    var i: Int = run {
        return@run 1
    }

    i = run {
        return@outer
    }
}

作用域

这里写图片描述

从作用域来看,标签和变量是一致的,都有相对应的作用于。在main方法里面定义了一个标签list@,在foo方法里面调用时,提示“Unresolved reference:@list”,意味着list标签的作用域应该在main方法里,在foo方法里并不能够调用。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值