Scala 2.12.15中break为何能跳出外部函数?技术咨询
问题分析:Scala中break跨方法生效的原因
环境信息
- Scala版本:scala-sdk-2.12.15
- JDK版本:jdk-8u371
- 操作系统:Win10
测试代码
import scala.util.control.Breaks.{break, breakable} object TestScala { def main(args: Array[String]) { a } def a { breakable { for (i <- 1 to 3) { println(i) b } } } def b { for (i <- 11 to 15) { if (i > 13) break println(i) } } }
实际运行结果(无任何警告)
1 11 12 13
预期的两种结果
情况1(编译失败)
error: value break is not a member of object Main.this.b if (i > 13) break ^
情况2(break无效)
1 11 12 13 2 11 12 13 3 11 12 13
问题原因解析
Scala里的break和breakable并非语法层面的跳转逻辑,而是基于异常实现的控制流机制:
break本质是抛出一个BreakControl类型的专属异常;breakable代码块的核心作用是捕获这个特定异常,一旦捕获就直接终止自身块内的所有代码执行。
在你的代码中:
- 方法
b里调用break时,会抛出BreakControl异常; - 异常沿调用栈向上传递,最终被方法
a中包裹外层for循环的breakable块捕获; - 捕获异常后,
breakable直接终止自身块内的所有代码,包括外层的for (i <- 1 to 3)循环,因此不会继续执行i=2、3的分支,最终得到你看到的运行结果。
你之前的两种预期都不符合Scala的实现逻辑:
- 编译不会失败:
break是通过import引入的顶层方法,方法b可以直接调用,不存在作用域限制; - break并非无效,而是它的作用范围被外层
breakable扩大,直接终止了整个外层循环。
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

