[英]Scala Trait with different def based on Type Parameter
我试图构建一个通用的 DAO,该 DAO 使用任一类型的具体类进行实例化:
我目前有一个描述可用方法的特征 DAO,get/create/upsert。 在编译时,我想根据我传递的类型参数更改/定义每个方法。 这是一些代码:
trait Regular {
id: int
}
trait Snap extends Regular {
isSnappy: Boolean = true
}
trait DAO[T<: Regular] {
def get(id: String)(implicit x: Param,ct: ClassTag[T]): Future[Either[String, T]]
}
如果特征是常规的:
def get(id:String)(implicit x: Param,ct: ClassTag[T]): Future[Either[String, T]] = {
//Handle regular trait flow
}
如果特征是 Snap <: 常规:
def get(id:String)(implicit x: Param,ct: ClassTag[T]): Future[Either[String, T]] = {
//Handle snappy
}
两个 defs 都会返回相同的类型 T。
我希望能够在编译时更改 def,在那里我了解 DAO 中的 Type 参数。 然后在运行时我希望能够实例化该类,但让它根据传递的类型处理 def。
我不确定如何在 Scala 中处理这个问题,无论是基于宏的解决方案,重载方法,还是为 Dao 定义的某种类型的隐式。 任何方向将不胜感激! 我不确定这是否是一个独特的问题,但我已经尽可能多地阅读了基于类型参数的编译时定义,同时仍然能够引用相同的特征(在这种情况下为 DAO)
对于这种情况,您可能需要一个类型类。 有很多关于这个的阅读,但这里有一个基于你的代码的简化版本的示例。
首先定义一个包含所有所需操作的类:
trait DaoOps[T] {
def get(id: String): Int
def create(id: String): T
def upsert(id: String): Int
}
然后使用每种类型的实现创建一个DaoOps
的implicit
实例:
trait Regular {
def id: Int
}
object Regular {
// DAO implementation for instances of Regular type
implicit object dao extends DaoOps[Regular] {
def get(id: String): Int = ???
def create(id: String): Regular = ???
def upsert(id: String): Int = ???
}
}
trait Snap extends Regular {
def isSnappy: Boolean = true
}
object Snap {
// DAO implementation for instances of Snap type
implicit object dao extends DaoOps[Snap] {
def get(id: String): Int = ???
def create(id: String): Snap = ???
def upsert(id: String): Int = ???
}
}
最后,使用主类中的 typeclass 为正在使用的特定类型选择实现:
trait DAO[T <: Regular] {
// Select the ops for the actual type of T
def get(id: String)(implicit ops: DaoOps[T]): Int =
ops.get(id)
}
implicit object
不必在伴随类中,但编译器会在那里寻找它们,从而避免必须显式地将它们带入作用域。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.