2011-08-27 46 views
4

我有采取了类似并返回可比性和包装另一个是做同样的事情方法的方法:视图绑定与上边界类型绑定不兼容?

def myMethod[T <: Comparable[T]](arg: T): T = otherMethod(arg) 
def otherMethod[T <: Comparable[T]](arg: T): T = arg 

这将编译,但不会允许我这样称呼myMethod的用int或任何其他类型这需要隐式转换才能实现Comparable。据我了解,鉴于界限旨在解决这类问题,但使用结合

def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg) 

我得到的编译器错误的观点:

inferred type arguments [T] do not conform to method otherMethod's type parameter bounds [T <: java.lang.Comparable[T]]

到目前为止,唯一的解决方法我已经拿出来就是使用第二种类型参数并且在两者之间施放:

def myMethod[T <% Comparable[T], U <: Comparable[U]](arg: T): T = 
    otherMethod(arg.asInstanceOf[U]).asInstanceOf[T] 

这个很有效,但很丑。有没有更好的办法?

回答

6

以下哪项工作?

  1. 使在这两种方法结合的相一致的T的视图,

    def otherMethod[T <% Comparable[T]](arg: T): T = arg 
    def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg) 
    
  2. 引入新类型参数U <: Comparable[U]和从TU的隐式转换,

    def otherMethod[T <: Comparable[T]](arg: T): T = arg 
    def myMethod[U <: Comparable[U], T <% U](arg: T): U = otherMethod(arg) 
    

问题与您的版本锡永是T <% Comparable[T]转换T键入Comparable[T],但这并不满足递归型T <: Comparable[T <: Comparable[T <: ...]]),该otherMethod期望。


更新。无论要使用otherMethodmyMethod与Scala的Int,你需要帮助的类型inferencer一点点,

myMethod(2)     // Int value types don't implement Comparable 
myMethod(2: java.lang.Integer) // Apply implicit conversion (Int => java.lang.Integer) 

更新2。在评论中,你说你愿意让myMethod有点丑陋,以改善呼叫站点的类型推断。这里有一个方法,

def myMethod[U <: Comparable[U], T](arg: T) 
    (implicit ev1: T => U, ev2: T => Comparable[U]): U = otherMethod(arg) 
myMethod(2) // returns java.lang.Integer(2) 

诀窍是使用两个隐式转换:ev1实际上得到应用,并ev2仅在那里的援助类型推断。后者要求Scala搜索其含义为Int => Comparable[U]类型的转换。在这种情况下,只能找到一个这样的转换,修复U = java.lang.Integer。请致电​​。您会看到ev1ev2参数都使用了相同的隐式Predef.int2Integer

旁注:这是最好的避免asInstanceOf蒙上因为这些失利Scala的类型系统的健全性。

+0

1.不,不幸的是,otherMethod在第三方库中定义。 2.是!这似乎工作。谢谢! – ethzero

+0

很高兴能帮到你:-) –

+0

其实,我说的太快了......第二种解决方案的确可以编译,但我仍然无法用Int来调用它。这里是错误:“类型参数[Int,Int]不符合方法myMethod的类型参数bounds [U <:java.lang.Comparable [U],T]” – ethzero

相关问题