从伴侣导入的类不可用作构造函数参数的默认值

时间:2017-04-08 11:58:20

标签: 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

}

为什么最后一个版本没有编译(与Config = Config.apply()相同)?

1 个答案:

答案 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

相关问题