我想要的东西,我已经看到了在不同环境下不同的形状之前没有: 延长Scala的查询扩展与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
ofcourse)。
我不知道如何输入这种隐式转换,以防止这种情况发生。可能吗?下面的“naieve”的解决方案不起作用,因为Scala现在的ID类型推断没有:
implicit class HasIdQueryExt[Id: BaseColumnType, U, T <: Table[U] with HasId[Id]]
(query: Query[T, U]) { ... }
我觉得有种奇怪的是,突然ID类型推断为无。如何提示编译器在哪里查找该Id类型?
我不熟悉的油滑,但我的猜测是,您的解决方案将需要一个泛型参数它采用你的表的实际类型......像'HasId [Id,T <:HasId [Id,T]]'。然后你可以用HasId作为参数T传递表的实际类型。编辑:另外,你有没有尝试过使用结构类型? http://java.dzone.com/articles/duck-typing-scala-structural这将使用反射,但仍然给你静态安全。 – 2014-09-20 16:08:21
我不明白这与我上次写下的方法有什么不同。这些不相等吗?在这种情况下,我认为结构打字不会有帮助。问题保留了它的结构。 – 2014-09-22 08:39:01