Scala 中如何使用 continue 和 break 跳出循环

梦里梦外; 2023-02-25 14:24 76阅读 0赞

示例代码:

  1. object Test {
  2. def main(args: Array[String]): Unit = {
  3. import scala.util.control.Breaks._
  4. println("=============== Continue ===================")
  5. for (i <- 1 to 10) {
  6. breakable {
  7. if (i % 2 == 0) {
  8. break
  9. }
  10. println(i)
  11. }
  12. }
  13. println("=============== Continue ===================")
  14. for (i <- 1 to 10 if i % 2 != 0) {
  15. println(i)
  16. }
  17. println("=============== Break ===================")
  18. breakable {
  19. for (i <- 1 to 10) {
  20. if (i % 2 == 0) {
  21. break
  22. }
  23. println(i)
  24. }
  25. }
  26. println("=============== Break ===================")
  27. var loop = true
  28. for (i <- 1 to 10 if loop == true) {
  29. if( i % 2 == 0){
  30. loop = false
  31. }
  32. println(i)
  33. }
  34. }
  35. }

查看Breaks源码得知,breakable 与 break 方法组合用于控制循环的原理就是利用 break 方法抛出一个异常,然后 breakable 方法再捕获这个异常,从而结束整个 breakable 方法块内代码的执行,但是不影响 breakable 方法体外代码的执行,从而实现控制。
源码如下:

  1. package scala
  2. package util.control
  3. /** A class that can be instantiated for the break control abstraction.
  4. * Example usage:
  5. * {
  6. {
  7. {
  8. * val mybreaks = new Breaks
  9. * import mybreaks.{break, breakable}
  10. *
  11. * breakable {
  12. * for (...) {
  13. * if (...) break()
  14. * }
  15. * }
  16. * }}}
  17. * Calls to break from one instantiation of `Breaks` will never
  18. * target breakable objects of some other instantiation.
  19. */
  20. class Breaks {
  21. private val breakException = new BreakControl
  22. /**
  23. * A block from which one can exit with a `break`. The `break` may be
  24. * executed further down in the call stack provided that it is called on the
  25. * exact same instance of `Breaks`.
  26. */
  27. def breakable(op: => Unit) {
  28. try {
  29. op
  30. } catch {
  31. case ex: BreakControl =>
  32. if (ex ne breakException) throw ex
  33. }
  34. }
  35. sealed trait TryBlock[T] {
  36. def catchBreak(onBreak: =>T): T
  37. }
  38. /**
  39. * This variant enables the execution of a code block in case of a `break()`:
  40. * {
  41. {
  42. {
  43. * tryBreakable {
  44. * for (...) {
  45. * if (...) break()
  46. * }
  47. * } catchBreak {
  48. * doCleanup()
  49. * }
  50. * }}}
  51. */
  52. def tryBreakable[T](op: =>T) = new TryBlock[T] {
  53. def catchBreak(onBreak: =>T) = try {
  54. op
  55. } catch {
  56. case ex: BreakControl =>
  57. if (ex ne breakException) throw ex
  58. onBreak
  59. }
  60. }
  61. /**
  62. * Break from dynamically closest enclosing breakable block using this exact
  63. * `Breaks` instance.
  64. *
  65. * @note This might be different than the statically closest enclosing block!
  66. */
  67. def break(): Nothing = { throw breakException }
  68. }
  69. /** An object that can be used for the break control abstraction.
  70. * Example usage:
  71. * {
  72. {
  73. {
  74. * import Breaks.{break, breakable}
  75. *
  76. * breakable {
  77. * for (...) {
  78. * if (...) break
  79. * }
  80. * }
  81. * }}}
  82. */
  83. object Breaks extends Breaks
  84. private class BreakControl extends ControlThrowable

发表评论

表情:
评论列表 (有 0 条评论,76人围观)

还没有评论,来说两句吧...

相关阅读