risc-v中文社区

 找回密码
 立即注册
查看: 1082|回复: 2

[原创] risc-v开发基础 Scala 循环中break/continue---(10)

  [复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-3 15:47:02 | 显示全部楼层 |阅读模式
在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
    }
  } 
}


回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-3 22:07:59 | 显示全部楼层
要理解scala的break需要理解:
1: op :=>Unit
就是一个带大括号的函数体代码,返回值是Unit即无返回值
2:break时就是抛出自定义的异常
3:breakable函数中捕获自定义的异常,当然不会真正出异常,但其它异常比如程序真发生了其它异常,则将此异常抛出
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-3 22:09:50 | 显示全部楼层
continue则建立在breakable基础之后,捕获自定义异常之后,代码还是在最外层的for循环体内,这样就相当于java中的continue功能了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-27 21:00 , Processed in 0.025247 second(s), 26 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表