2015-08-20 2 views
2

У меня есть класс 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 can доступ eA вне класс.

Кажется, компилятор решает, что можно повторно использовать selfType поле eA, что было бы здорово, если бы он не нарушал доступ к eA в Scala-отражения.

+0

Я не могу воспроизвести его в РЕПЛ, 'Скала> classOf [collection.mutable.ArrayBuilder.ofRef [_]] getDeclaredFields res0:. Array [java.lang.reflect.Field] = Array (частный окончательный scala.reflect.ClassTag scala.collection.mutable.ArrayBuilder $ ofRef.evidence $ 2, ' – 4e6

+0

Проблема возникает с конкретным классом. Если это произошло всегда, это было бы замечено давно. Я попытаюсь свести его к минимуму завтра. –

+0

Да, я вижу, я могу воспроизвести его, когда класс расширяет один с аргументом неявного значения, как с 'class BaseDef [T] (неявный val s: Elem [T])'. ** val ** имеет решающее значение – 4e6

ответ

2

Reply from Jason Zaugg on scala-user:

Компилятор позволяет избежать избыточных полей в подклассах, если он статически определяет, что значение хранится в поле в супер-класса, который выставляет его через доступную аксессору.

Чтобы предотвратить это, вы можете изменить конструктор суперкласса, удалив ключевое слово val и добавив еще один val в этот класс, который хранит этот параметр.

 Смежные вопросы

  • Нет связанных вопросов^_^