2011-11-19 85 views
3

我正在改进Querydsl中的Scala支持,并遇到以下问题。下面是一个代码片段,说明了这个问题:Scala中的隐式转换问题

// 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

在这种特定的情况下,以下变化工作:

implicit def toAdapter[T, R <: RelationalPath[T]](p: RelationalPath[T] with R) = 
    new RelationalPathAdapter[T,R](p) 
+0

感谢。这确实有诀窍! –

3

这是不是一个真正的隐式转换的问题,而是一个类型推断的问题。当你调用适配器(路径)时,没有任何隐含的。

如果你传递了类型参数,它就起作用了。

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) 
+0

它似乎没有工作。试试这个:val conv:RelationalPathAdapter [User,QUser] = toAdapter(path) –

+0

尽管如此,它仍然可以解决你原来的问题,就像你可以做'path.someMethod'一样。但很好,关于'QUser'的信息丢失了,你只有'RelationalPathAdapter [User,RelationalPath [User]]'。那么阿列克谢的解决方案就是这样。 –

+0

是的,我的问题不够明确。感谢您的努力。 –