Estoy mejorando el soporte de Scala en Querydsl y encontré el siguiente problema. Aquí hay un fragmento de código que ilustra el problema:
// 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
Cómo hacer coincidir un tipo en una conversión implícita además de su argumento de tipo. Puedo hacer coincidir ambos por separado, pero no ambos.
Respuestas
4 para la respuesta № 1En este caso específico, funciona el siguiente cambio:
implicit def toAdapter[T, R <: RelationalPath[T]](p: RelationalPath[T] with R) =
new RelationalPathAdapter[T,R](p)
3 para la respuesta № 2
Esto no es realmente un problema de conversión implícita, sino un problema de inferencia de tipos. Cuando llama a toAdapter (ruta), no hay nada implícito.
Si pasa el parámetro tipo, funciona.
toAdapter[User, QUser](path).someMethod
Incluso puede funcionar con una conversión implícita:
(path: RelationalPathAdapter[User, QUser]).someMethod
pero, por supuesto, esto es bastante inútil.
La forma correcta de escribir lo implícito es
implicit def toAdapter[T, R[X] <: RelationalPath[X]](p: R[T])
= new RelationalPathAdapter[T, R[T]](p)