Scala模棱两可的案例类生成并伴随应用方法

时间:2019-10-29 05:20:25

标签: scala

给出以下代码:

case class Foo(bar: String)
object Foo{
  def apply(bar: String): Foo = Foo(bar)
}

如果我要调用Foo("foo"),我将最终对def apply(bar: String)进行无限递归调用。当然,可以通过将Apply实现更改为def apply(bar: String): Foo = new Foo(bar)来解决此问题。但是,如果我理解正确,则会为带有所有构造函数参数的案例类生成一个apply方法。那么我的问题有两个:

1)如果我自己编写然后自动生成了Foo.apply(bar: String): Foo,为什么我没有收到抱怨重复方法定义的编译错误?

2)如果生成的方法具有不同的签名,该怎么称呼它?

1 个答案:

答案 0 :(得分:4)

  

为什么我没有抱怨重复的方法定义的编译错误?

因为您的apply()代码替换了case class自动生成的代码。它们不会同时存在。

这可以通过编译代码但在编译的“类型”阶段(阶段4)之后转储中间状态来证明。

%%> cat so.sc
case class Foo(bar: String)
object Foo{
  def apply(bar: String): Foo = Foo(bar)
}
%%> scalac -Xprint:4 so.sc | less

结果输出只有一个object,只有一种apply()方法。

  object Foo extends scala.AnyRef with Serializable {
    def <init>(): Foo.type = {
      Foo.super.<init>();
      ()
    };
    def apply(bar: String): Foo = Foo.apply(bar);
    case <synthetic> def unapply(x$0: Foo): Option[String] = if (x$0.==(null))
      scala.None
    else
      Some.apply[String](x$0.bar);
    <synthetic> private def readResolve(): Object = Foo
  }

如您所见,递归apply()方法位于自动生成的<synthetic>代码中。