繁体   English   中英

基于类型参数具有不同定义的 Scala Trait

[英]Scala Trait with different def based on Type Parameter

我试图构建一个通用的 DAO,该 DAO 使用任一类型的具体类进行实例化:

  1. 常规的
  2. 活泼的 <:常规

我目前有一个描述可用方法的特征 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
}

然后使用每种类型的实现创建一个DaoOpsimplicit实例:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM