IntelliJ IDEA中Scala Worksheet的函数定义顺序是否重要?
Scala Worksheet 中函数定义顺序的影响
是的,你遇到的情况完全正常——Scala Worksheet 里的函数定义顺序确实会影响代码能否正常运行,背后的原因和 Scala 本身的编译规则直接相关。
为什么顺序会有影响?
Scala 是静态编译型语言,在同一个作用域(比如你直接在 Worksheet 顶级定义的这些函数)中,编译器需要在处理函数调用时,已经知晓被调用函数的完整定义。当你把 sqrtIter 放在 isGoodEnough 和 improve 前面时,编译器解析 sqrtIter 里的 isGoodEnough(guess, x) 调用时,还未读取到这两个辅助函数的定义,自然会抛出「Not found」的错误。
而把 isGoodEnough 和 improve 移到 sqrtIter 上方后,编译器在处理 sqrtIter 的逻辑前,已经获取到了这两个函数的签名与实现,所以就能正常编译执行了。
如何避免顺序依赖?
如果你不想受定义顺序的限制,可以把相关函数封装到一个 object(或 class)中。在 Scala 的类/对象作用域里,成员方法的定义顺序是无关紧要的——编译器会先整体解析整个类/对象的所有成员,再处理方法间的调用。比如修改成这样:
def abs(x:Double) = if (x < 0) -x else x object SqrtUtils { def sqrtIter(guess: Double, x: Double): Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(guess, x), x) def isGoodEnough(guess: Double, x: Double) = abs(guess * guess - x ) / x < 0.001 def improve(guess: Double, x: Double) = (guess + x / guess) / 2 } // 调用示例 SqrtUtils.sqrtIter(1.0, 4.0)
这样即使 sqrtIter 放在辅助函数前面,代码也能正常运行,因为 SqrtUtils 对象的所有成员会被编译器一次性解析完成。
内容的提问来源于stack exchange,提问作者Saverio Guzzo
相关产品推荐
相关产品推荐

