Я вдосконалюю підтримку Scala в Querydsl і зіткнувся з наступною проблемою. Ось фрагмент коду, який ілюструє проблему:
// framework types
class RelationalPath[T]
class RelationalPathAdapter[T, R <: RelationalPath[T]](p: R) { def someMethod = {} }
// domain types
class User
class QUser extends RelationalPath[User]
implicit def toAdapter[T, R <: RelationalPath[T]](p: R) = new RelationalPathAdapter[T,R](p)
val path = new QUser()
toAdapter(path).someMethod // DOESN"T COMPILE
path.someMethod // DOESN"T COMPILE
Як зіставити тип у неявній конверсії на додаток до аргументу типу. Я можу відповідати або окремо, але не обидва.
Відповіді:
4 для відповіді № 1У цьому конкретному випадку працює наступна зміна:
implicit def toAdapter[T, R <: RelationalPath[T]](p: RelationalPath[T] with R) =
new RelationalPathAdapter[T,R](p)
3 для відповіді № 2
Це насправді не неявна проблема перетворення, скоріше проблема виводу типу. Коли ви зателефонуєте в AdApter (шлях), нічого неявного.
Якщо ви передаєте параметр типу, він працює.
toAdapter[User, QUser](path).someMethod
Він навіть може працювати з неявною конверсією:
(path: RelationalPathAdapter[User, QUser]).someMethod
але, звичайно, це досить марно.
Правильним способом написання неявного є
implicit def toAdapter[T, R[X] <: RelationalPath[X]](p: R[T])
= new RelationalPathAdapter[T, R[T]](p)