当超类中存在具有相同类型的隐式 val 时,编译器不会为隐式 val 生成字段
Compiler doesn't generate a field for implicit val when an implicit val with the same type is present in the superclass
我有一个classFoo
定义如下:
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(JNIExtractorOps.scala:15)
at scalan.Test$delayedInit$body.apply(JNIExtractorOps.scala:11)
是否有对此的解释或者这是一个已知错误(Scala 版本是 2.11.7)?我 可以 从 class.
外部访问 eA
似乎编译器决定它可以为 eA
重用 selfType
字段,如果它不中断在 scala-reflect 中对 eA
的访问,那就太好了。
Reply from Jason Zaugg on scala-user:
The compiler avoids redundant fields in subclasses if it statically determines that the value is stored in a field in a super class that exposes it via an accessible accessor.
To prevent this, you might be able to change the superclass constructor by removing the val keyword and add another val to that class that stores the parameter.
我有一个classFoo
定义如下:
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(JNIExtractorOps.scala:15)
at scalan.Test$delayedInit$body.apply(JNIExtractorOps.scala:11)
是否有对此的解释或者这是一个已知错误(Scala 版本是 2.11.7)?我 可以 从 class.
外部访问eA
似乎编译器决定它可以为 eA
重用 selfType
字段,如果它不中断在 scala-reflect 中对 eA
的访问,那就太好了。
Reply from Jason Zaugg on scala-user:
The compiler avoids redundant fields in subclasses if it statically determines that the value is stored in a field in a super class that exposes it via an accessible accessor.
To prevent this, you might be able to change the superclass constructor by removing the val keyword and add another val to that class that stores the parameter.