我想要的東西,我已經看到了在不同環境下不同的形狀之前沒有: 延長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