Return 扩展特征的案例 class
Return a case class that extends a trait
我需要为 return 定义一个扩展特征的案例 class:
trait Id {
def id: Long
}
case class Person(name: String)
val john = Person("John")
val johnWithId: Person with Id = /*person -> 123L*/ ???
知道如何实现吗?
我正在努力减少代码的重复,这就是为什么我没有像这样声明一个特征 Person 的原因:
trait Id {
def id: Long
}
trait Person {
def name: String
}
case class PersonWithoutId(name: String) extends Person
case class PersonWithId(name: String, id: Long) extends Person with Id
val john = PersonWithoutId("John")
val johnWithId: Person with Id = PersonWithId(person.name, 123L)
知道如何实现吗?
val johnWithId: Person with Id = new Person("John") with Id { def id = 123L }
一旦 Person
已经实例化,就太晚了 - 您无法在实例化后更改实例 john
。但是,您可以实例化 Person with Id
:
val johnWithId: Person with Id = new Person("John") with Id {
override def id: Long = 123L
}
请注意,这实际上 等同于 使用 PersonWithId(name: String, id: Long)
案例 class,例如 - equals
和 hashcode
将 忽略 此实现中的 ID。
有点迂回:
case class WithId[A](id: Long, value: A) extends Id
object WithId {
implicit def getValue[A](x: WithId[A]): A = x.value
}
// elsewhere
val johnWithId = WithId(123, john)
johnWithId
不会扩展 Person
(因此 johnWithId.isInstanceOf[Person]
是错误的),但仍然可以在需要 Person
和 [=15= 的地方使用].
最正确的解决方案是
case class Person(name: String, id: Long) extends Id
理论上你可以做到
val johnWithId: Person with Id = new Person("John") with Id { def id = 123L }
如 Andrey 所述,它不会遵守整个 case class
合同,因为具有不同 ID 和相同姓名的人是平等的,因为 id
不会用于 equals
方法
我需要为 return 定义一个扩展特征的案例 class:
trait Id {
def id: Long
}
case class Person(name: String)
val john = Person("John")
val johnWithId: Person with Id = /*person -> 123L*/ ???
知道如何实现吗?
我正在努力减少代码的重复,这就是为什么我没有像这样声明一个特征 Person 的原因:
trait Id {
def id: Long
}
trait Person {
def name: String
}
case class PersonWithoutId(name: String) extends Person
case class PersonWithId(name: String, id: Long) extends Person with Id
val john = PersonWithoutId("John")
val johnWithId: Person with Id = PersonWithId(person.name, 123L)
知道如何实现吗?
val johnWithId: Person with Id = new Person("John") with Id { def id = 123L }
一旦 Person
已经实例化,就太晚了 - 您无法在实例化后更改实例 john
。但是,您可以实例化 Person with Id
:
val johnWithId: Person with Id = new Person("John") with Id {
override def id: Long = 123L
}
请注意,这实际上 等同于 使用 PersonWithId(name: String, id: Long)
案例 class,例如 - equals
和 hashcode
将 忽略 此实现中的 ID。
有点迂回:
case class WithId[A](id: Long, value: A) extends Id
object WithId {
implicit def getValue[A](x: WithId[A]): A = x.value
}
// elsewhere
val johnWithId = WithId(123, john)
johnWithId
不会扩展 Person
(因此 johnWithId.isInstanceOf[Person]
是错误的),但仍然可以在需要 Person
和 [=15= 的地方使用].
最正确的解决方案是
case class Person(name: String, id: Long) extends Id
理论上你可以做到
val johnWithId: Person with Id = new Person("John") with Id { def id = 123L }
如 Andrey 所述,它不会遵守整个 case class
合同,因为具有不同 ID 和相同姓名的人是平等的,因为 id
不会用于 equals
方法