【发布时间】:2014-09-20 15:00:02
【问题描述】:
我正在尝试一些我以前在不同情况下以不同形状看到的东西:
使用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 类型推断出 Nothing:
implicit class HasIdQueryExt[Id: BaseColumnType, U, T <: Table[U] with HasId[Id]]
(query: Query[T, U]) { ... }
我觉得有点奇怪,突然 Id 类型被推断为 Nothing。如何提示编译器在哪里查找该 Id 类型?
【问题讨论】:
-
我对 Slick 不熟悉,但我的猜测是,您的解决方案需要一个通用参数,该参数采用您的表的实际类型......类似于 'HasId[Id, T <: hasid t href="http://java.dzone.com/articles/duck-typing-scala-structural" rel="nofollow" target="_blank">java.dzone.com/articles/duck-typing-scala-structural 这将使用反射,但仍为您提供静态安全。
-
我看不出这与我上次写下的方法有何不同。那些不是等价的吗?而且我认为结构类型在这种情况下没有帮助。问题保留了它的结构。
标签: scala generics implicit-conversion type-inference slick