Метод копирования класса case отсутствует

У меня возникли проблемы с пониманием того, почему метод copy не создается/не подбирается в случае класса TestCaseClassStore.

abstract class IdStore {
  self =>
  type Entity
  type Ref <: IdRef[_]
  type Self <: IdStore {type Entity = self.Entity; type Ref = self.Ref}

  def copy(data: Map[Ref, Entity]): Self

  def data: Map[Ref, Entity]

  def merge(other: Self): Self = copy(data ++ other.data)
}

trait IdRef[T] {
  def id: T
}

case class IntIdRef(id:Int) extends IdRef[Int]

class TestStore(val data: Map[IntIdRef, Object]) extends IdStore {
  override type Entity = Object
  override type Ref = IntIdRef
  override type Self = TestStore

  override def copy(newData: Map[Ref, Entity]): Self = new TestStore(newData)

  override def toString() = "TestStore(" + data + ")"
}

case class TestCaseClassStore(data: Map[IntIdRef, Object]) extends IdStore {
  override type Entity = Object
  override type Ref = IntIdRef
  override type Self = TestCaseClassStore
}

object Main extends App {
    val data = Map(IntIdRef(1) -> "target 1", IntIdRef(2) -> "target 2"); 

    val classic = new TestStore(data)
    println(classic.copy(classic.data))

    val caseClass = new TestCaseClassStore(data)
    println(caseClass.copy(caseClass.data))
}

Это заканчивается ошибкой неопределенного метода:

Main.scala:30: error: class TestCaseClassStore needs to be abstract, since method copy in class IdStore of type (data: Map[TestCaseClassStore.this.Ref,TestCaseClassStore.this.Entity])TestCaseClassStore.this.Self is not defined
case class TestCaseClassStore(data: Map[IntIdRef, Object]) extends IdStore {
           ^
one error found

Если я добавлю следующую строку в класс case, она сработает, но совершенно бесполезна, потому что основной причиной, по которой я хотел использовать класс case, был автоматически сгенерированный метод копирования.

  override def copy(newData: Map[Ref, Entity]): Self = TestCaseClassStore(newData)

  • Почему метод copy отсутствует в TestCaseClassStore? Возможно, ограничение компилятора или языка? Или я неправильно реализовал суперкласс (но класс TestStore работает)?

  • Есть ли какой-нибудь краткий способ написать больше реализаций IdStore (желательно без повторения метода copy или даже как-то абстрагировать типы Entity и Ref в конструкторе, чтобы они упоминались только один раз в определении типа)?


person monnef    schedule 14.02.2016    source источник


Ответы (1)


Компилятор не генерирует метод копирования, если он уже существует.

Вы можете видеть, что, добавив реализацию метода копирования в суперклассе, он не будет перезаписан. Подозреваю, что это намеренно.

person dth    schedule 14.02.2016
comment
намеренно, см. scala -lang.org/files/archive/spec/2.11/ - person som-snytt; 15.02.2016
comment
Таким образом, несмотря на то, что copy в IdStore является абстрактным, он по-прежнему считается присутствующим, и генерация пропускается :-(. Спасибо за разъяснения. - person monnef; 15.02.2016