请考虑以下代码:
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
}
为什么最后一个版本没有编译(与Config = Config.apply()
相同)?
答案 0 :(得分:2)
我不清楚这是否是一个错误,但这就是它产生错误的原因:
考虑一下,这有效:
import Project._
object Project {
case class Config()
}
case class Project(config: Config = Config())
添加默认参数时,编译器会生成一个计算值的方法。当该值是构造函数默认值时,该方法将添加到类的伴随对象中。所以编译器会生成这个方法:
def <init>$default$1: Project.Config = Config()
哪些内容会添加到您的Project
对象中。
Scala类型检查器生成Contexts
的对象树。每个上下文都引用了它的外部范围的上下文。因此,生成的方法获取上下文,生成的方法的外部范围是Project
伴随对象。
当类型检查器尝试解析Config()
时,它会遍历所有封闭的上下文,但找不到Config
(我不知道为什么,这可能是一个错误)。
一旦用完了上下文,就会解析导入Project._
的导入!类型检查器很高兴,因为它现在可以遍历导入并找到apply方法。
现在,当您将导入移至Project
下方
object Project {
case class Config()
}
import Project._
case class Project(config: Config = Config())
在这种情况下,生成的方法可用的导入没有Project._
导入(这也可能是一个错误),我假设因为它低于生成的方法所在的对象定义。然后类型检查器会抛出错误,因为它找不到Config
。
似乎正在发生的事情是当类型检查器解析Config()
时,它需要在Project
随播广告对象上方导入,因为它需要处理导入才能解析它,除非导入高于Project
,导入不在范围内。
对于那些希望进一步调试的人,请查看发现查找的Contexts.lookupSymbol