2

鉴于此代码:

object Testy extends App {

  case class Person(
                     id: Option[Long],
                     firstName: String,
                     lastName: String,
                     address: Address)

  case class Address(id: Option[Long],
                     name: String,
                     number: Int)

  val personOrAddress:AnyRef= Person(Some(1L), "first", "last", Address(Some(1L), "street", 1))
  type HasCopyMethodWithId = _
  val newId = Some(123L)
  personOrAddress.asInstanceOf[HasCopyMethodWithId].copy(id = newId)
}

如何实现'type HasCopyMethodWithId',以便此代码编译并且在运行时不会失败?

我试过了:

type HasCopyMethodWithId = {def copy(id: Option[Long]): AnyRef}
4

1 回答 1

4

案例类提供的合成copy方法是具有该案例类的所有参数的单个方法,而不是单个重载的 foridfirstName。因此结构类型不匹配。

您可以添加一个辅助方法:

case class Person(id: Option[Long],
                  firstName: String,
                  lastName: String,
                  address: Address) {

  def copyId(newId: Option[Long]): Person = copy(id = newId)
}

case class Address(id: Option[Long],
                   name: String,
                   number: Int) {
  def copyId(newId: Option[Long]): Address = copy(id = newId)
}

val personOrAddress: Any = 
  Person(Some(1L), "first", "last", Address(Some(1L), "street", 1))

type HasCopyMethodWithId = { def copyId(id: Option[Long]): Any }
val newId = Some(123L)
personOrAddress.asInstanceOf[HasCopyMethodWithId].copyId(id = newId)

但几乎可以肯定更好的是提供静态类型:

trait CopyWithId { 
  type Repr 
  def copyId(id: Option[Long]): Repr
}

case class Person(id: Option[Long],
                  firstName: String,
                  lastName: String,
                  address: Address) extends CopyWithId {

  type Repr = Person
  def copyId(newId: Option[Long]): Person = copy(id = newId)
}

case class Address(id: Option[Long],
                   name: String,
                   number: Int) extends CopyWithId {

  type Repr = Address
  def copyId(newId: Option[Long]): Address = copy(id = newId)
}

val personOrAddress: CopyWithId = 
  Person(Some(1L), "first", "last", Address(Some(1L), "street", 1))

val newId = Some(123L)
personOrAddress.copyId(id = newId)
于 2016-01-18T11:54:07.387 回答