当超类中存在具有相同类型的隐式val时,编译器不会为隐式val生成字段

时间:2015-08-20 12:57:11

标签: scala reflection scala-2.11

我的课程Foo定义如下:

class Elem[A]

abstract class BaseDef[T](implicit val selfType: Elem[T])

case class Foo[A, T]()(implicit val eA: Elem[A], val eT: Elem[T]) extends BaseDef[A]

令我惊讶的是,getDeclaredFields 包含eA

object Test extends App {
  private val fields = classOf[Foo[_, _]].getDeclaredFields

  println(fields.mkString("\n"))
  assert(fields.exists(_.getName == "eA"))
}

产生

private final scalan.Elem scalan.Foo.eT    
Exception in thread "main"
java.lang.AssertionError: assertion failed
    at scala.Predef$.assert(Predef.scala:151)
    at scalan.Test$.delayedEndpoint$scalan$Test$1(JNIExtractorOps.scala:15)
    at scalan.Test$delayedInit$body.apply(JNIExtractorOps.scala:11)

是否有解释或这是一个已知错误(Scala版本是2.11.7)?我可以从课堂外访问eA

似乎编译器决定它可以重用selfType的{​​{1}}字段,如果它没有在scala-reflect中破坏eA的访问权限,那将会很棒。

1 个答案:

答案 0 :(得分:2)

Reply from Jason Zaugg on scala-user

  

如果子类静态地确定该值存储在通过可访问的访问器公开它的超类中的字段中,则编译器会避免子类中的冗余字段。

     

为了防止这种情况,您可以通过删除val关键字来更改超类构造函数,并为存储该参数的类添加另一个val。