I am attempting to define a base trait used for a simple CRUD system. However, I need the base trait to support a "copyWithId" def (since the Scala case class magic for copy is not available). The best approach I have found so far is:
trait Identifiable[ID, T] {
def id: Option[ID]
def copyWithId(id: Option[ID]): T
}
case class TestNamedIdentity(id: Option[Int], name: String)
extends Identifiable[Int, TestNamedIdentity] {
def copyWithId(id: Option[Int]): TestNamedIdentity = {
copy(id = id)
}
}
This works but looks a bit clunky because it requires all the concrete instances to extend with ID and Self. I'd like to write something like the following:
trait Identifiable[ID] {
this:X =>
def copyWithId(id: Option[ID]): X
def id: Option[ID]
}
Using some form of self-reference to the concrete class. Any way to make this work?
Update: With use case below
The idea is to use it in code like
abstract class SomeClass[A <: IdentifiableEntity[ID], ID] {
def someFunc2: Option[ID]
def someFunc(item: A): A = {
item.copyWithId(someFunc2)
}
}
Using the solution from @jwvh requires "asInstanceOf" casting after the call. Which for my use case works, but was hoping for a more elegant solution.
item.copyWithId(someFunc2).asInstanceOf[A]
This appears to work.
trait Identifiable[ID] {
def id: Option[ID]
def copyWithId(id: Option[ID]): Identifiable[ID]
}
Then the case class is simplified.
case class TestNamedIdentity(id: Option[Int], name: String
) extends Identifiable[Int] {
def copyWithId(id: Option[Int]): TestNamedIdentity = copy(id = id)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.