如何在Scala中定义泛型类型?

如何在Scala中定义泛型类型?,scala,slick,Scala,Slick,在Slick 2中,我们可以映射如下表: case class Cooler(id: Option[Int], minTemp: Option[Double], maxTemp: Option[Double]) /** * Define table "cooler". */ class Coolers(tag: Tag) extends Table[Cooler](tag, "cooler") { def id = column[Int]("id", O.PrimaryKey, O.A

在Slick 2中,我们可以映射如下表:

case class Cooler(id: Option[Int], minTemp: Option[Double], maxTemp: Option[Double])

/**
 * Define table "cooler".
 */
class Coolers(tag: Tag) extends Table[Cooler](tag, "cooler") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def minTemp = column[Double]("min_temp", O.Nullable)
  def maxTemp = column[Double]("max_temp", O.Nullable)

  def * = (id.?, minTemp.?, maxTemp.?) <> (Cooler.tupled, Cooler.unapply _)
}

object Coolers {
  val tableQuery = TableQuery[Coolers]
}
但是我在
tableQuery
定义上收到一个错误:

需要类类型,但找不到


有人知道我做错了什么吗?

当你执行
TableQuery[T]
时,你实际上是在调用
TableQuery.apply,它是

此宏的主体尝试实例化
T
,但在您的情况下,T已成为编译器不知道如何实例化的(未知)类型参数。问题类似于试图编译以下内容:

def instantiate[T]: T = new T
// Does not compile ("class type required but T found")
净效果是
TableQuery.apply
只能用于具体类型

可以绕过该问题(在已知具体类型的点上)以及隐式宏来提供该类型类的实例。然后你会有这样的想法:

abstract class TableUtils[T <: Table[A] : TableQueryBuilder, A] {
  val tableQuery = BuildTableQuery[T]
}
这里有一个解决方案:

首先,定义它以避免类类型问题

class Service[T <: Table[_]](path: String, cons: Tag => T){

  lazy val db = Database.forConfig(path)

  def query = TableQuery[T](cons)
}

此解决方案在slick 3.x中测试正常,并使用slick 1.x,因为slick 2.0 Query.scala符合slick 3.0 Query.scala,这可能也适用于2。

使用上一种方法,我收到以下错误:
TableQuery的类型参数数目错误,应该是1
。实施时有什么特别的考虑吗?或者它有一个有效的实现吗?它们似乎在版本
2.0.0-M3
2.0.0
之间改变了
TableQuery
。尝试将
val tableQuery:tableQuery[T,T#TableElementType]
替换为
val tableQuery:tableQuery[T]
我已经为相关答案实际实现了类型类(
TableQueryBuilder
)解决方案。看见
abstract class TableUtils[T <: Table[A] , A] {
  val tableQuery: TableQuery[T, T#TableElementType]
  // define here your helper methods operating on `tableQuery`
}
object Coolers extends TableUtils[Coolers, Cooler] {
  val tableQuery = TableQuery[Coolers]
}
class Service[T <: Table[_]](path: String, cons: Tag => T){

  lazy val db = Database.forConfig(path)

  def query = TableQuery[T](cons)
}
object Abcd {

  object Def extends Service[Post]("mydb", abc) {



    def test = {


      //db

      val q = query.drop(1).take(20)
      val r = db.run(q.result)

      println(q.result.statements.head)
      println(r)

      r

    }
  }

  private def abc(tag: Tag) = new Post(tag)

}