|
在java中,循环内可以很容易使用break或continue处理跳出或继续逻辑,而scala中没有这样的关键字,
因为这二个关键字与scala所提倡的函数式编程风格不相符,所以scala中通过增加scala.util.control.Breaks类来达到相应的目的。
先将如何使用的代码框架描述如下,以便后面看源代码时好分析:
val mybreaks = new Breaks
import mybreaks.{break, breakable}
breakable {
for (...) {
if (...) break()
}
}
Breaks类的源代码:
class Breaks {
private val breakException = new BreakControl
def breakable(op:=>Unit){
try{
op //op是一个参数,但这个参数是一个函数,函数不需要输入参数,输出是Unit即无输出,此处op语句表示调用这个函数,不能写成op()
//如果breakable(op)=>Unit)语法形式定义的话,则此处必须要用op()表示调用
} catch {
case ex:BreakControl => if (ex ne breakException) throw ex //模式匹配为BreakControl类型匹配 ,根据前面如何使用的代码框架可知,
//用户在使用过程中需要break时,会调用break(),也就是我们的op这一句中会出现break()调用,根据下面def break()中定义,会抛出breakException
//这个异常类型是我们自定义的异常类型,当然会被本异常捕获捕获到,当然也不会真正再throw ex,只有是用户其它异常,才会throw ex
}
}
def break():Nothing = { throw breakException}
}
object Breaks extends Breaks //这个语法还有点不明白?
private class BreakControl extends ControlThrowable
(类ControlThrowable是一个trait,其定义为:trait ControlThrowable extends Throwable with NoStackTrackTrace
也就是说是异常trait,并且是不需要处理异常堆栈信息的异常trait,这很容易理解,我们只想跳出一段代码逻辑,并不是
真正的异常,所以不需要异常堆栈信息)
举一个例子:
import scala.util.control.Breaks;
object BreakTest {
def main(args: Array[String]): Unit = {
val breakInst = new Breaks
import breakInst._
breakable {
var values = 10
while(values >0) {
if(values == 5) break
println(values)
values -= 1
}
}
println("over")
}
}
显示如下:
10
9
8
7
6
over
//注意:从语法形式上来说,breakable{}中的{}就表示:op:=>xxx,至于说{}中返回的是什么类型,则xxx也要对应成什么类型。
//上面介绍的是break,如果是continue则代码框架如下:
for(){
breakable{
if(){
break // 这里的break,只是跳出breakable函数范围,但还在for循环中,这就相当于java中的continue
}
}
}
|
|