scala - trait - 为什么case类伴随对象扩展了FunctionN?




scala<: (3)

case类伴随对象实现FunctionN的原因是之前,case类生成了一个类和一个工厂方法,而不是一个伴随对象。 当我们向Scala添加提取器时,使用apply和unapply方法将工厂方法转换为完整的伴随对象更有意义。 但是,由于工厂方法确实符合FunctionN,因此伴随对象也需要符合。

[编辑]也就是说,将伴侣对象显示为自己的名称而不是“功能”是有意义的

创建案例类时,编译器会创建一个对应的伴随对象,其中包含一些案例类的好处:与主构造函数匹配的apply工厂方法, equalshashCodecopy

奇怪的是,这个生成的对象扩展了FunctionN。

scala> case class A(a: Int)                                 
defined class A

scala> A: (Int => A)
res0: (Int) => A = <function1>

只有在以下情况下才会这样:

  • 没有手动定义的伴随对象
  • 只有一个参数列表
  • 没有类型参数
  • 案例类不是抽象的。

似乎这是大约两年前added 。 最新的化身就here

有没有人使用它,或者知道它为什么被添加? 它使用静态转发器方法稍微增加了生成的字节码的大小,并显示在随#toString()对象的#toString()方法中:

scala> case class A()
defined class A

scala> A.toString
res12: java.lang.String = <function0>

UPDATE

使用单个apply方法手动创建的对象不会自动视为FunctionN

object HasApply {
  def apply(a: Int) = 1
}
val i = HasApply(1)

// fails
//  HasApply: (Int => Int) 

好吧,鉴于Scala中的target.apply(a1, a2, a3 ... aN)

  1. 可以被target(a1, a2, a3 ... aN)加糖
  2. 是需要由FunctionN实现的方法

一个伴侣对象似乎很自然:

object MyClass {
  def apply(a1 : A1, ... aN: AN) = new MyClass(a1, ..., aN)
}

是真的:

object MyClass extends FunctionN[A1, ... , AN, MyClass]{
  def apply(a1 : A1, ... aN: AN) = new MyClass(a1, ..., aN)
}

所以添加对我来说似乎很自然(我不确定为什么它对你来说似乎“奇怪”?)。 至于它是否真的添加了任何东西; 好吧,那是为了比我聪明的人!


Welcome to Scala version 2.8.0.RC3 (Java HotSpot(TM) Client VM, Java 1.6.0_20).

scala> case class CC3(i: Int, b: Boolean, s: String)
defined class CC3

scala> CC3
res0: CC3.type = <function3>

scala> CC3.apply(1, true, "boo!")
res1: CC3 = CC3(1,true,boo!)

scala> CC3(1, true, "boo!")
res2: CC3 = CC3(1,true,boo!)




companion-object