gpt4 book ai didi

Scala 编译器对泛型参数没有任何推断

转载 作者:行者123 更新时间:2023-12-03 17:18:31 24 4
gpt4 key购买 nike

我正在尝试一些我之前在不同上下文中以不同形状看到的东西:
使用 filterById(id: Id) 扩展 Scala 的查询扩展

这是我尝试过的:

trait TableWithId { self: Profile =>

import profile.simple._

trait HasId[Id] { self: Table[_] =>
def id: Column[Id]
}

implicit class HasIdQueryExt[Id: BaseColumnType, U]
(query: Query[Table[U] with HasId[Id], U]) {
def filterById(id: Id)(implicit s: Session) = query.filter(_.id === id)
def insertReturnId(m: U)(implicit s: Session): Id = query.returning(query.map(_.id)) += m
}
}

这很好用,没有真正的魔法。但是由于 Table 类型没有类型约束,我应用 filterById 的任何查询都会失去它的特异性(现在是通用的 Table with HasId[Id] ),并且我无法再访问它的列(当然, _.id 除外) .

我不知道如何键入这种隐式转换,从而防止这种情况发生。是否可以?以下“天真的”解决方案不起作用,因为 Scala 现在对 Id 类型没有任何推断:
implicit class HasIdQueryExt[Id: BaseColumnType, U, T <: Table[U] with HasId[Id]]
(query: Query[T, U]) { ... }

我觉得奇怪的是,突然 Id 类型被推断为 Nothing。如何提示编译器在哪里查找该 Id 类型?

最佳答案

这是我对类似问题的解决方案。不过,我确实使用了特定类型的 id。:

trait GenericComponent { this: Profile =>
import profile.simple._

abstract class TableWithId[A](tag:Tag, name:String) extends Table[A](tag:Tag, name) {
def id = column[Option[UUID]]("id", O.PrimaryKey)
}

abstract class genericTable[T <: Table[A] , A] {
val table: TableQuery[T]

/**
* generic methods
*/

def insert(entry: A)(implicit session:Session): A = session.withTransaction {
table += entry
entry
}

def insertAll(entries: List[A])(implicit session:Session) = session.withTransaction { table.insertAll(entries:_*) }

def all: List[A] = database.withSession { implicit session =>
table.list.map(_.asInstanceOf[A])
}
}

/**
* generic queries for any table which has id:Option[UUID]
*/
abstract class genericTableWithId[T <: TableWithId[A], A <:ObjectWithId ] extends genericTable[T, A] {

def forIds(ids:List[UUID]): List[A] = database.withSession { implicit session =>
ids match {
case Nil => Nil
case x::xs =>table.filter(_.id inSet(ids)).list.map(_.asInstanceOf[A])
}
}

def forId(id:UUID):Option[A] = database.withSession { implicit session =>table.filter(_.id === id).firstOption }

}
}

然后对于您的具体组件:
case class SomeObjectRecord(
override val id:Option[UUID] = None,
name:String) extends ObjectWithId(id){
// your function definitions there
}

trait SomeObjectComponent extends GenericComponent { this: Profile =>
import profile.simple._

class SomeObjects(tag: Tag) extends TableWithId[SomeObjectRecord](tag, "some_objects") {
def name = column[String]("name", O.NotNull)

def * = (id, name) <> (SomeObjectRecord.tupled, SomeObjectRecord.unapply)
def nameIdx = index("u_name", (name), unique = true)
}

object someobjects extends genericTableWithId[SomeObjects, SomeObjectRecord] {
val table = TableQuery[Units]

// your additional methods there; you get insert and insertAll from the parent
}
}

关于Scala 编译器对泛型参数没有任何推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25950068/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com