将泛型定义为案例类

  • 本文关键字:案例 定义 泛型 scala
  • 更新时间 :
  • 英文 :


在这个例子中,我希望泛型Tcase classDAOEntityid,所以在抽象实现中,我可以使用copy方法。

如何定义它?

trait DAOEntity {
def id: String
}
// How to define this generic to force the use of a `case class` to have access to `copy`?
abstract class DAO[T <: DAOEntity] {
def storeInUppercase(entity: T): T = entity.copy(id = entity.id)
}
case class MyEntity(id: String) extends DAOEntity
class MyEntityDAO extends DAO[MyEntity] {
// Other stuff
}

无法知道一个类型是否是case class
即使有,也不会得到copy方法。该语言没有提供对构造函数进行抽象的方法;因此CCD_ 8和工厂(CCD_。这是有道理的,这样的函数的类型签名是什么?

相反,您可以创建一个类似typeclass的工厂,并要求:

trait DAOFactory[T <: DAOEntity] {
def copy(oldEntity: T, newId: String): T
}
object DAOFactory {
def instance[T <: DAOEntity](f: (T, String) => T): DAOFactory[T] =
new DAOFactory[T] {
override final def copy(oldEntity: T, newId: String): T =
f(oldEntity, newId)
}
}

可以这样使用:

abstract class DAO[T <: DAOEntity](implicit factory: DAOFactory[T]) {
def storeInUppercase(entity: T): T =
factory.copy(
oldEntity = entity,
newId = entity.id.toUpperCase
)
}

实体会提供这样的例子:

final case class MyEntity(id: String, age: Int) extends DAOEntity
object MyEntity {
implicit final val MyEntityFactory: DAOFactory[MyEntity] =
DAOFactory.instance {
case (oldEntity, newId) =>
oldEntity.copy(id = newId)
}
}
// This compile thanks to the instance in the companion object.
object MyEntityDAO extends DAO[MyEntity]

您可以在此处看到运行的代码

最新更新