使用Slick Table的Scala类型推断
有这样的模型(简化):
case class User(id:Int,name:String) case class Address(id:Int,name:String) ... Slick(2.1.0版)表映射: class Users(_tableTag: Tag) extends Table[User](_tableTag,"users") with WithId[Users,User] {` val id: Column[Int] = column[Int]("id",O.AutoInc,O.PrimaryKey) ... } trait WithId[T,R] { this: Table[R] => def id: Column[Int] } 混合特征WithId我想为列id为不同的表实现通用DAO方法:Column [Int](我希望方法findById能够同时处理用户和地址表映射) trait GenericSlickDAO[T <: WithId[T,R],R] { def db: Database def findById(id: Int)(implicit stk: SlickTableQuery[T]): Option[R] = db.withSession { implicit session => stk.tableQuery.filter(_.id === id).list.headOption } trait SlickTableQuery[T] { def tableQuery: TableQuery[T] } object SlickTableQuery { implicit val usersQ = new SlickTableQuery[Users] { val tableQuery: Table Query[Users] = Users } } 问题是findById无法编译:
我认为T的类型为WithId [T,同时类型为Table [R]. Slick实现Table类型,如果X = Table [Y]则X#TableElementType = Y. 所以在我的情况下,T#TableElementType = R和Option [T#TableElementType]应该被推断为Option [R],但事实并非如此.我哪里错了? 解决方法
你对WithId [T,R]属于Table [R]类型的假设是错误的. WithId [T,R]中的自我类型注释只需要混合表[R],但这并不意味着WithId [T,R]是表[R].
我认为你混淆WithId的声明与WithId的实例最终需要是一个Table的实例. GenericSlickDAO特征中的上限类型约束也不保证WithId的属性是Table的实例,因为任何类型都是其自身的子类型. 有关自我类型和子类型之间差异的更详细解释,请参阅this问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |