Scala编译器不推断泛型参数

Scala编译器不推断泛型参数,scala,generics,implicit-conversion,type-inference,slick,Scala,Generics,Implicit Conversion,Type Inference,Slick,我正在尝试一些我以前在不同环境中见过的不同形状的东西: 使用filterById(id:id) 这就是我尝试过的: trait TableWithId { self: Profile => import profile.simple._ trait HasId[Id] { self: Table[_] => def id: Column[Id] } implicit class HasIdQueryExt[Id: BaseColumn

我正在尝试一些我以前在不同环境中见过的不同形状的东西: 使用
filterById(id:id)

这就是我尝试过的:

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
    }
}
这很好,没有真正的魔力。但是由于表类型没有类型约束,我应用filterById的任何查询都会失去它的特殊性(现在是一个带有HasId[Id]的泛型
表),并且我无法再访问它的列(当然
..Id
除外)

我不知道如何键入这个隐式转换,这样就可以防止这种情况。可能吗?以下“naieve”解决方案不起作用,因为Scala现在无法推断Id类型:

implicit class HasIdQueryExt[Id: BaseColumnType, U, T <: Table[U] with HasId[Id]]
(query: Query[T, U]) { ... }

隐式类HasIdQueryExt[Id:BaseColumnType,U,T这是我针对类似问题的解决方案。不过我确实为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 }

  }
}
trait-GenericComponent{this:Profile=>
导入profile.simple_
抽象类TableWithId[A](标记:标记,名称:字符串)扩展表[A](标记:标记,名称){
def id=列[选项[UUID](“id”,O.PrimaryKey)
}
抽象类泛型[T]
table.list.map(u.asInstanceOf[A])
}
}
/**
*对id为Option[UUID]的任何表的通用查询
*/
抽象类genericTableWithId[T Nil
case x::xs=>table.filter(u.id inSet(id)).list.map(u.asInstanceOf[A])
}
}
def-forId(id:UUID):选项[A]=database.withSession{implicit session=>table.filter(u.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    
  }
}
case类SomeObjectRecord(
覆盖值id:选项[UUID]=无,
名称:字符串)扩展ObjectWithId(id){
//这里有你的函数定义
} 
trait SomeObjectComponent扩展了GenericComponent{this:Profile=>
导入profile.simple_
类SomeObjects(tag:tag)扩展了TableWithId[SomeObjectRecord](tag,“some_对象”){
def name=列[字符串](“名称”,O.NotNull)
def*=(id,名称)(SomeObjectRecord.tuple,SomeObjectRecord.unapply)
def nameIdx=索引(“u_name”,(name),unique=true)
}
对象someobjects扩展了genericTableWithId[someobjects,SomeObjectRecord]{
val table=表格查询[单位]
//您可以从父级获取insert和insertAll
}
}

我不熟悉Slick,但我猜,您的解决方案需要一个通用参数,该参数采用表的实际类型……类似于“HasId”[Id,T我看不出这与我上次写下的方法有什么不同。这些方法是否等效?我认为结构类型在这种情况下没有帮助。问题保留了它的结构。谢谢。但这当然不能回答我的问题;它解决了问题。因为你的建议是:删除Id此外,我更喜欢QueryExtensions而不是方法的伴生对象,因为查询的扩展可以在任何查询给出特定结果形状的地方重用,而您的附加方法只能用于sich。