Sum*_*uma 7 scala companion-object
考虑以下代码:
object Main extends App {
object Project {
case class Config(rules: Seq[String] = Seq.empty)
}
import Project._
//case class Project(root: String, config: Config) // compiles fine
//case class Project(root: String, config: Project.Config = Project.Config()) // compiles fine
case class Project(root: String, config: Config = Config()) // error: not found: type Config
}
Run Code Online (Sandbox Code Playgroud)
为什么最后一个版本没有编译(与之相同Config = Config.apply()
)?
我不清楚这是否是一个错误,但这就是它产生错误的原因:
考虑一下这个,它有效:
import Project._
object Project {
case class Config()
}
case class Project(config: Config = Config())
Run Code Online (Sandbox Code Playgroud)
当您添加默认参数时,编译器会生成一个方法来计算该值。当该值是构造函数默认值时,该方法将添加到该类的伴随对象中。所以编译器会生成这个方法:
def <init>$default$1: Project.Config = Config()
Run Code Online (Sandbox Code Playgroud)
它将被添加到您的Project
对象中。
Scala 类型检查器生成一个Contexts
. 每个上下文都有对其外部范围的上下文的引用。因此生成的方法获得一个上下文,并且该生成的方法的外部作用域是Project
伴随对象。
当类型检查器尝试解析时,Config()
它会遍历所有封闭的上下文并且无法找到Config
(我不确定为什么,这可能是一个错误)。
Project._
一旦它耗尽了上下文,它就会解析具有 import !的导入。类型检查器很高兴,因为它现在可以遍历导入并找到 apply 方法。
现在,当您将导入移动到下面时Project
:
object Project {
case class Config()
}
import Project._
case class Project(config: Config = Config())
Run Code Online (Sandbox Code Playgroud)
在这种情况下,生成的方法可用的导入没有导入Project._
(这也可能是一个错误),我假设是因为它位于生成的方法所在的对象定义下方。然后类型检查器会抛出错误,因为它找不到Config
.
似乎发生的情况是,当类型检查器解析时,Config()
它需要在伴生对象之上进行导入Project
,因为它需要处理导入才能解析它,除非导入高于Project
该导入,否则导入不在范围内。
对于那些希望进一步调试的人,请查看Contexts.lookupSymbol
查找发生的位置