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



我有一个类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)?I 可以从类外访问eA

似乎编译器决定它可以重用selfType字段为eA,这将是伟大的,如果它没有破坏访问eA在scala-reflect

Jason Zaugg关于scala-user的回复:

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

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

相关内容

  • 没有找到相关文章

最新更新